diff options
Diffstat (limited to 'hw')
240 files changed, 1828 insertions, 1248 deletions
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index b15838c..9345aae 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -76,6 +76,20 @@ int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf) err = -errno; } }); + /* + * Some FS driver (local:mapped-file) can't support fetching attributes + * using file descriptor. Use Path name in that case. + */ + if (err == -EOPNOTSUPP) { + err = v9fs_co_lstat(pdu, &fidp->path, stbuf); + if (err == -ENOENT) { + /* + * fstat on an unlinked file. Work with partial results + * returned from s->ops->fstat + */ + err = 0; + } + } return err; } diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 3f15540..b8220ab 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -91,15 +91,6 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) s->ctx.fs_root = NULL; } s->ctx.exops.get_st_gen = NULL; - - if (fse->export_flags & V9FS_SM_PASSTHROUGH) { - s->ctx.xops = passthrough_xattr_ops; - } else if (fse->export_flags & V9FS_SM_MAPPED) { - s->ctx.xops = mapped_xattr_ops; - } else if (fse->export_flags & V9FS_SM_NONE) { - s->ctx.xops = none_xattr_ops; - } - len = strlen(conf->tag); if (len > MAX_TAG_LEN - 1) { fprintf(stderr, "mount tag '%s' (%d bytes) is longer than " @@ -193,10 +184,10 @@ static TypeInfo virtio_9p_info = { .class_init = virtio_9p_class_init, }; -static void virtio_9p_register_devices(void) +static void virtio_9p_register_types(void) { type_register_static(&virtio_9p_info); virtio_9p_set_fd_limit(); } -device_init(virtio_9p_register_devices) +type_init(virtio_9p_register_types) diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index cb012c0..f96d17a 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -63,11 +63,11 @@ static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp) if (fd < 0) { return fd; } - ret = fchmod(fd, credp->fc_mode & 07777); + ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH); if (ret < 0) { goto err_out; } - ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH); + ret = fchmod(fd, credp->fc_mode & 07777); err_out: close(fd); return ret; diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 3ae6ef2..33a41d2 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -20,6 +20,7 @@ #include <sys/socket.h> #include <sys/un.h> #include "qemu-xattr.h" +#include <libgen.h> #include <linux/fs.h> #ifdef CONFIG_LINUX_MAGIC_H #include <linux/magic.h> @@ -39,6 +40,54 @@ #define BTRFS_SUPER_MAGIC 0x9123683E #endif +#define VIRTFS_META_DIR ".virtfs_metadata" + +static const char *local_mapped_attr_path(FsContext *ctx, + const char *path, char *buffer) +{ + char *dir_name; + char *tmp_path = strdup(path); + char *base_name = basename(tmp_path); + + /* NULL terminate the directory */ + dir_name = tmp_path; + *(base_name - 1) = '\0'; + + snprintf(buffer, PATH_MAX, "%s/%s/%s/%s", + ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name); + free(tmp_path); + return buffer; +} + +#define ATTR_MAX 100 +static void local_mapped_file_attr(FsContext *ctx, const char *path, + struct stat *stbuf) +{ + FILE *fp; + char buf[ATTR_MAX]; + char attr_path[PATH_MAX]; + + local_mapped_attr_path(ctx, path, attr_path); + fp = fopen(attr_path, "r"); + if (!fp) { + return; + } + memset(buf, 0, ATTR_MAX); + while (fgets(buf, ATTR_MAX, fp)) { + if (!strncmp(buf, "virtfs.uid", 10)) { + stbuf->st_uid = atoi(buf+11); + } else if (!strncmp(buf, "virtfs.gid", 10)) { + stbuf->st_gid = atoi(buf+11); + } else if (!strncmp(buf, "virtfs.mode", 11)) { + stbuf->st_mode = atoi(buf+12); + } else if (!strncmp(buf, "virtfs.rdev", 11)) { + stbuf->st_rdev = atoi(buf+12); + } + memset(buf, 0, ATTR_MAX); + } + fclose(fp); +} + static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) { int err; @@ -71,10 +120,103 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) sizeof(dev_t)) > 0) { stbuf->st_rdev = tmp_dev; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + local_mapped_file_attr(fs_ctx, path, stbuf); } return err; } +static int local_create_mapped_attr_dir(FsContext *ctx, const char *path) +{ + int err; + char attr_dir[PATH_MAX]; + char *tmp_path = strdup(path); + + snprintf(attr_dir, PATH_MAX, "%s/%s/%s", + ctx->fs_root, dirname(tmp_path), VIRTFS_META_DIR); + + err = mkdir(attr_dir, 0700); + if (err < 0 && errno == EEXIST) { + err = 0; + } + free(tmp_path); + return err; +} + +static int local_set_mapped_file_attr(FsContext *ctx, + const char *path, FsCred *credp) +{ + FILE *fp; + int ret = 0; + char buf[ATTR_MAX]; + char attr_path[PATH_MAX]; + int uid = -1, gid = -1, mode = -1, rdev = -1; + + fp = fopen(local_mapped_attr_path(ctx, path, attr_path), "r"); + if (!fp) { + goto create_map_file; + } + memset(buf, 0, ATTR_MAX); + while (fgets(buf, ATTR_MAX, fp)) { + if (!strncmp(buf, "virtfs.uid", 10)) { + uid = atoi(buf+11); + } else if (!strncmp(buf, "virtfs.gid", 10)) { + gid = atoi(buf+11); + } else if (!strncmp(buf, "virtfs.mode", 11)) { + mode = atoi(buf+12); + } else if (!strncmp(buf, "virtfs.rdev", 11)) { + rdev = atoi(buf+12); + } + memset(buf, 0, ATTR_MAX); + } + fclose(fp); + goto update_map_file; + +create_map_file: + ret = local_create_mapped_attr_dir(ctx, path); + if (ret < 0) { + goto err_out; + } + +update_map_file: + fp = fopen(attr_path, "w"); + if (!fp) { + ret = -1; + goto err_out; + } + + if (credp->fc_uid != -1) { + uid = credp->fc_uid; + } + if (credp->fc_gid != -1) { + gid = credp->fc_gid; + } + if (credp->fc_mode != -1) { + mode = credp->fc_mode; + } + if (credp->fc_rdev != -1) { + rdev = credp->fc_rdev; + } + + + if (uid != -1) { + fprintf(fp, "virtfs.uid=%d\n", uid); + } + if (gid != -1) { + fprintf(fp, "virtfs.gid=%d\n", gid); + } + if (mode != -1) { + fprintf(fp, "virtfs.mode=%d\n", mode); + } + if (rdev != -1) { + fprintf(fp, "virtfs.rdev=%d\n", rdev); + } + fclose(fp); + +err_out: + return ret; +} + static int local_set_xattr(const char *path, FsCred *credp) { int err; @@ -115,9 +257,6 @@ static int local_post_create_passthrough(FsContext *fs_ctx, const char *path, { char buffer[PATH_MAX]; - if (chmod(rpath(fs_ctx, path, buffer), credp->fc_mode & 07777) < 0) { - return -1; - } if (lchown(rpath(fs_ctx, path, buffer), credp->fc_uid, credp->fc_gid) < 0) { /* @@ -128,6 +267,10 @@ static int local_post_create_passthrough(FsContext *fs_ctx, const char *path, return -1; } } + + if (chmod(rpath(fs_ctx, path, buffer), credp->fc_mode & 07777) < 0) { + return -1; + } return 0; } @@ -138,7 +281,8 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path, char buffer[PATH_MAX]; char *path = fs_path->data; - if (fs_ctx->export_flags & V9FS_SM_MAPPED) { + if ((fs_ctx->export_flags & V9FS_SM_MAPPED) || + (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) { int fd; fd = open(rpath(fs_ctx, path, buffer), O_RDONLY); if (fd == -1) { @@ -203,7 +347,18 @@ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, struct dirent *entry, struct dirent **result) { - return readdir_r(fs->dir, entry, result); + int ret; + +again: + ret = readdir_r(fs->dir, entry, result); + if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + if (!ret && *result != NULL && + !strcmp(entry->d_name, VIRTFS_META_DIR)) { + /* skp the meta data directory */ + goto again; + } + } + return ret; } static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) @@ -264,6 +419,8 @@ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) if (fs_ctx->export_flags & V9FS_SM_MAPPED) { return local_set_xattr(rpath(fs_ctx, path, buffer), credp); + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + return local_set_mapped_file_attr(fs_ctx, path, credp); } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode); @@ -296,6 +453,18 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, serrno = errno; goto err_end; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + + err = mknod(rpath(fs_ctx, path, buffer), + SM_LOCAL_MODE_BITS|S_IFREG, 0); + if (err == -1) { + goto out; + } + err = local_set_mapped_file_attr(fs_ctx, path, credp); + if (err == -1) { + serrno = errno; + goto err_end; + } } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { err = mknod(rpath(fs_ctx, path, buffer), credp->fc_mode, @@ -344,6 +513,17 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, serrno = errno; goto err_end; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + err = mkdir(rpath(fs_ctx, path, buffer), SM_LOCAL_DIR_MODE_BITS); + if (err == -1) { + goto out; + } + credp->fc_mode = credp->fc_mode|S_IFDIR; + err = local_set_mapped_file_attr(fs_ctx, path, credp); + if (err == -1) { + serrno = errno; + goto err_end; + } } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { err = mkdir(rpath(fs_ctx, path, buffer), credp->fc_mode); @@ -404,6 +584,9 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, &tmp_dev, sizeof(dev_t)) > 0) { stbuf->st_rdev = tmp_dev; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + errno = EOPNOTSUPP; + return -1; } return err; } @@ -436,6 +619,19 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, serrno = errno; goto err_end; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + fd = open(rpath(fs_ctx, path, buffer), flags, SM_LOCAL_MODE_BITS); + if (fd == -1) { + err = fd; + goto out; + } + credp->fc_mode = credp->fc_mode|S_IFREG; + /* Set client credentials in .virtfs_metadata directory files */ + err = local_set_mapped_file_attr(fs_ctx, path, credp); + if (err == -1) { + serrno = errno; + goto err_end; + } } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { fd = open(rpath(fs_ctx, path, buffer), flags, credp->fc_mode); @@ -506,6 +702,35 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, serrno = errno; goto err_end; } + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + int fd; + ssize_t oldpath_size, write_size; + fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR, + SM_LOCAL_MODE_BITS); + if (fd == -1) { + err = fd; + goto out; + } + /* Write the oldpath (target) to the file. */ + oldpath_size = strlen(oldpath); + do { + write_size = write(fd, (void *)oldpath, oldpath_size); + } while (write_size == -1 && errno == EINTR); + + if (write_size != oldpath_size) { + serrno = errno; + close(fd); + err = -1; + goto err_end; + } + close(fd); + /* Set cleint credentials in symlink's xattr */ + credp->fc_mode = credp->fc_mode|S_IFLNK; + err = local_set_mapped_file_attr(fs_ctx, newpath, credp); + if (err == -1) { + serrno = errno; + goto err_end; + } } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { err = symlink(oldpath, rpath(fs_ctx, newpath, buffer)); @@ -548,6 +773,21 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath, ret = link(rpath(ctx, oldpath->data, buffer), rpath(ctx, newpath.data, buffer1)); + + /* now link the virtfs_metadata files */ + if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) { + /* Link the .virtfs_metadata files. Create the metada directory */ + ret = local_create_mapped_attr_dir(ctx, newpath.data); + if (ret < 0) { + goto err_out; + } + ret = link(local_mapped_attr_path(ctx, oldpath->data, buffer), + local_mapped_attr_path(ctx, newpath.data, buffer1)); + if (ret < 0 && errno != ENOENT) { + goto err_out; + } + } +err_out: v9fs_string_free(&newpath); return ret; } @@ -563,8 +803,21 @@ static int local_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size) static int local_rename(FsContext *ctx, const char *oldpath, const char *newpath) { + int err; char buffer[PATH_MAX], buffer1[PATH_MAX]; + if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + err = local_create_mapped_attr_dir(ctx, newpath); + if (err < 0) { + return err; + } + /* rename the .virtfs_metadata files */ + err = rename(local_mapped_attr_path(ctx, oldpath, buffer), + local_mapped_attr_path(ctx, newpath, buffer1)); + if (err < 0 && errno != ENOENT) { + return err; + } + } return rename(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1)); } @@ -580,6 +833,8 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) credp->fc_uid, credp->fc_gid); } else if (fs_ctx->export_flags & V9FS_SM_MAPPED) { return local_set_xattr(rpath(fs_ctx, path, buffer), credp); + } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { + return local_set_mapped_file_attr(fs_ctx, path, credp); } return -1; } @@ -595,8 +850,46 @@ static int local_utimensat(FsContext *s, V9fsPath *fs_path, static int local_remove(FsContext *ctx, const char *path) { + int err; + struct stat stbuf; char buffer[PATH_MAX]; + + if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + err = lstat(rpath(ctx, path, buffer), &stbuf); + if (err) { + goto err_out; + } + /* + * If directory remove .virtfs_metadata contained in the + * directory + */ + if (S_ISDIR(stbuf.st_mode)) { + sprintf(buffer, "%s/%s/%s", ctx->fs_root, path, VIRTFS_META_DIR); + err = remove(buffer); + if (err < 0 && errno != ENOENT) { + /* + * We didn't had the .virtfs_metadata file. May be file created + * in non-mapped mode ?. Ignore ENOENT. + */ + goto err_out; + } + } + /* + * Now remove the name from parent directory + * .virtfs_metadata directory + */ + err = remove(local_mapped_attr_path(ctx, path, buffer));; + if (err < 0 && errno != ENOENT) { + /* + * We didn't had the .virtfs_metadata file. May be file created + * in non-mapped mode ?. Ignore ENOENT. + */ + goto err_out; + } + } return remove(rpath(ctx, path, buffer)); +err_out: + return err; } static int local_fsync(FsContext *ctx, int fid_type, @@ -696,12 +989,45 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir, int ret; V9fsString fullname; char buffer[PATH_MAX]; + v9fs_string_init(&fullname); v9fs_string_sprintf(&fullname, "%s/%s", dir->data, name); + if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + if (flags == AT_REMOVEDIR) { + /* + * If directory remove .virtfs_metadata contained in the + * directory + */ + sprintf(buffer, "%s/%s/%s", ctx->fs_root, + fullname.data, VIRTFS_META_DIR); + ret = remove(buffer); + if (ret < 0 && errno != ENOENT) { + /* + * We didn't had the .virtfs_metadata file. May be file created + * in non-mapped mode ?. Ignore ENOENT. + */ + goto err_out; + } + } + /* + * Now remove the name from parent directory + * .virtfs_metadata directory. + */ + ret = remove(local_mapped_attr_path(ctx, fullname.data, buffer)); + if (ret < 0 && errno != ENOENT) { + /* + * We didn't had the .virtfs_metadata file. May be file created + * in non-mapped mode ?. Ignore ENOENT. + */ + goto err_out; + } + } + /* Remove the name finally */ ret = remove(rpath(ctx, fullname.data, buffer)); v9fs_string_free(&fullname); +err_out: return ret; } @@ -736,6 +1062,19 @@ static int local_init(FsContext *ctx) int err = 0; struct statfs stbuf; + if (ctx->export_flags & V9FS_SM_PASSTHROUGH) { + ctx->xops = passthrough_xattr_ops; + } else if (ctx->export_flags & V9FS_SM_MAPPED) { + ctx->xops = mapped_xattr_ops; + } else if (ctx->export_flags & V9FS_SM_NONE) { + ctx->xops = none_xattr_ops; + } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { + /* + * xattr operation for mapped-file and passthrough + * remain same. + */ + ctx->xops = passthrough_xattr_ops; + } ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT; #ifdef FS_IOC_GETVERSION /* @@ -770,13 +1109,17 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse) if (!strcmp(sec_model, "passthrough")) { fse->export_flags |= V9FS_SM_PASSTHROUGH; - } else if (!strcmp(sec_model, "mapped")) { + } else if (!strcmp(sec_model, "mapped") || + !strcmp(sec_model, "mapped-xattr")) { fse->export_flags |= V9FS_SM_MAPPED; } else if (!strcmp(sec_model, "none")) { fse->export_flags |= V9FS_SM_NONE; + } else if (!strcmp(sec_model, "mapped-file")) { + fse->export_flags |= V9FS_SM_MAPPED_FILE; } else { fprintf(stderr, "Invalid security model %s specified, valid options are" - "\n\t [passthrough|mapped|none]\n", sec_model); + "\n\t [passthrough|mapped-xattr|mapped-file|none]\n", + sec_model); return -1; } diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index e6ba6ba..a72ffc3 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -986,7 +986,7 @@ static void v9fs_attach(void *opaque) s->root_fid = fid; /* disable migration */ error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION, - s->ctx.fs_root, s->tag); + s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag); migrate_add_blocker(s->migration_blocker); out: put_fid(pdu, fidp); @@ -1391,7 +1391,6 @@ static void v9fs_open(void *opaque) err = -EROFS; goto out; } - flags |= O_NOATIME; } err = v9fs_co_open(pdu, fidp, flags); if (err < 0) { diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c index 19de12b..03b128c 100644 --- a/hw/a9mpcore.c +++ b/hw/a9mpcore.c @@ -238,9 +238,9 @@ static TypeInfo a9mp_priv_info = { .class_init = a9mp_priv_class_init, }; -static void a9mp_register_devices(void) +static void a9mp_register_types(void) { type_register_static(&a9mp_priv_info); } -device_init(a9mp_register_devices) +type_init(a9mp_register_types) @@ -1372,9 +1372,9 @@ static TypeInfo ac97_info = { .class_init = ac97_class_init, }; -static void ac97_register (void) +static void ac97_register_types (void) { type_register_static (&ac97_info); } -device_init (ac97_register); +type_init (ac97_register_types) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 21484ae..d959f49 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -426,12 +426,12 @@ static TypeInfo piix4_pm_info = { .class_init = piix4_pm_class_init, }; -static void piix4_pm_register(void) +static void piix4_pm_register_types(void) { type_register_static(&piix4_pm_info); } -device_init(piix4_pm_register); +type_init(piix4_pm_register_types) static uint32_t gpe_readb(void *opaque, uint32_t addr) { diff --git a/hw/ads7846.c b/hw/ads7846.c index 3cfdecb..41c7f10 100644 --- a/hw/ads7846.c +++ b/hw/ads7846.c @@ -168,9 +168,9 @@ static TypeInfo ads7846_info = { .class_init = ads7846_class_init, }; -static void ads7846_register_devices(void) +static void ads7846_register_types(void) { type_register_static(&ads7846_info); } -device_init(ads7846_register_devices) +type_init(ads7846_register_types) diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c index 736c28a..b539416 100644 --- a/hw/alpha_typhoon.c +++ b/hw/alpha_typhoon.c @@ -824,8 +824,9 @@ static TypeInfo typhoon_pcihost_info = { .class_init = typhoon_pcihost_class_init, }; -static void typhoon_register(void) +static void typhoon_register_types(void) { type_register_static(&typhoon_pcihost_info); } -device_init(typhoon_register); + +type_init(typhoon_register_types) diff --git a/hw/apb_pci.c b/hw/apb_pci.c index c7aaa72..1d25da8 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -493,11 +493,11 @@ static TypeInfo pbm_pci_bridge_info = { .class_init = pbm_pci_bridge_class_init, }; -static void pbm_register_devices(void) +static void pbm_register_types(void) { type_register_static(&pbm_host_info); type_register_static(&pbm_pci_host_info); type_register_static(&pbm_pci_bridge_info); } -device_init(pbm_register_devices) +type_init(pbm_register_types) @@ -781,9 +781,9 @@ static TypeInfo apic_info = { .class_init = apic_class_init, }; -static void apic_register_devices(void) +static void apic_register_types(void) { type_register_static(&apic_info); } -device_init(apic_register_devices) +type_init(apic_register_types) diff --git a/hw/apic_common.c b/hw/apic_common.c index 8373d79..c91f7d5 100644 --- a/hw/apic_common.c +++ b/hw/apic_common.c @@ -318,9 +318,9 @@ static TypeInfo apic_common_type = { .abstract = true, }; -static void register_devices(void) +static void register_types(void) { type_register_static(&apic_common_type); } -device_init(register_devices); +type_init(register_types) diff --git a/hw/applesmc.c b/hw/applesmc.c index b06487f..8bedaad 100644 --- a/hw/applesmc.c +++ b/hw/applesmc.c @@ -243,9 +243,9 @@ static TypeInfo applesmc_isa_info = { .class_init = qdev_applesmc_class_init, }; -static void applesmc_register_devices(void) +static void applesmc_register_types(void) { type_register_static(&applesmc_isa_info); } -device_init(applesmc_register_devices) +type_init(applesmc_register_types) diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c index 3c0839c..102348b 100644 --- a/hw/arm11mpcore.c +++ b/hw/arm11mpcore.c @@ -252,10 +252,10 @@ static TypeInfo mpcore_priv_info = { .class_init = mpcore_priv_class_init, }; -static void arm11mpcore_register_devices(void) +static void arm11mpcore_register_types(void) { type_register_static(&mpcore_rirq_info); type_register_static(&mpcore_priv_info); } -device_init(arm11mpcore_register_devices) +type_init(arm11mpcore_register_types) diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c index ba26abc..09f290c 100644 --- a/hw/arm_l2x0.c +++ b/hw/arm_l2x0.c @@ -184,9 +184,9 @@ static TypeInfo l2x0_info = { .class_init = l2x0_class_init, }; -static void l2x0_register_device(void) +static void l2x0_register_types(void) { type_register_static(&l2x0_info); } -device_init(l2x0_register_device) +type_init(l2x0_register_types) diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c index 5a02365..361e887 100644 --- a/hw/arm_mptimer.c +++ b/hw/arm_mptimer.c @@ -335,9 +335,9 @@ static TypeInfo arm_mptimer_info = { .class_init = arm_mptimer_class_init, }; -static void arm_mptimer_register_devices(void) +static void arm_mptimer_register_types(void) { type_register_static(&arm_mptimer_info); } -device_init(arm_mptimer_register_devices) +type_init(arm_mptimer_register_types) diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index 9d25799..149c639 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -425,9 +425,9 @@ static TypeInfo arm_sysctl_info = { .class_init = arm_sysctl_class_init, }; -static void arm_sysctl_register_devices(void) +static void arm_sysctl_register_types(void) { type_register_static(&arm_sysctl_info); } -device_init(arm_sysctl_register_devices) +type_init(arm_sysctl_register_types) diff --git a/hw/arm_timer.c b/hw/arm_timer.c index 1019d41..e3ecce2 100644 --- a/hw/arm_timer.c +++ b/hw/arm_timer.c @@ -383,10 +383,10 @@ static TypeInfo sp804_info = { .class_init = sp804_class_init, }; -static void arm_timer_register_devices(void) +static void arm_timer_register_types(void) { type_register_static(&icp_pit_info); type_register_static(&sp804_info); } -device_init(arm_timer_register_devices) +type_init(arm_timer_register_types) diff --git a/hw/armv7m.c b/hw/armv7m.c index de3d7e0..6b80579 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -266,9 +266,9 @@ static TypeInfo bitband_info = { .class_init = bitband_class_init, }; -static void armv7m_register_devices(void) +static void armv7m_register_types(void) { type_register_static(&bitband_info); } -device_init(armv7m_register_devices) +type_init(armv7m_register_types) diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index 1ed0abc..3210129 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -417,9 +417,9 @@ static TypeInfo armv7m_nvic_info = { .class_init = armv7m_nvic_class_init, }; -static void armv7m_nvic_register_devices(void) +static void armv7m_nvic_register_types(void) { type_register_static(&armv7m_nvic_info); } -device_init(armv7m_nvic_register_devices) +type_init(armv7m_nvic_register_types) diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c index c9c1182..44ed7f4 100644 --- a/hw/bitbang_i2c.c +++ b/hw/bitbang_i2c.c @@ -237,9 +237,9 @@ static TypeInfo gpio_i2c_info = { .class_init = gpio_i2c_class_init, }; -static void bitbang_i2c_register(void) +static void bitbang_i2c_register_types(void) { type_register_static(&gpio_i2c_info); } -device_init(bitbang_i2c_register) +type_init(bitbang_i2c_register_types) diff --git a/hw/bonito.c b/hw/bonito.c index 7350a4f..77786f8 100644 --- a/hw/bonito.c +++ b/hw/bonito.c @@ -804,9 +804,10 @@ static TypeInfo bonito_pcihost_info = { .class_init = bonito_pcihost_class_init, }; -static void bonito_register(void) +static void bonito_register_types(void) { type_register_static(&bonito_pcihost_info); type_register_static(&bonito_info); } -device_init(bonito_register); + +type_init(bonito_register_types) diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c index 9510ed4..f4a6da4 100644 --- a/hw/ccid-card-emulated.c +++ b/hw/ccid-card-emulated.c @@ -594,9 +594,9 @@ static TypeInfo emulated_card_info = { .class_init = emulated_class_initfn, }; -static void ccid_card_emulated_register_devices(void) +static void ccid_card_emulated_register_types(void) { type_register_static(&emulated_card_info); } -device_init(ccid_card_emulated_register_devices) +type_init(ccid_card_emulated_register_types) diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c index a7006ca..bd6c777 100644 --- a/hw/ccid-card-passthru.c +++ b/hw/ccid-card-passthru.c @@ -343,9 +343,9 @@ static TypeInfo passthru_card_info = { .class_init = passthru_class_initfn, }; -static void ccid_card_passthru_register_devices(void) +static void ccid_card_passthru_register_types(void) { type_register_static(&passthru_card_info); } -device_init(ccid_card_passthru_register_devices) +type_init(ccid_card_passthru_register_types) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index a8e8ab7..4edcb94 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2923,12 +2923,6 @@ static TypeInfo isa_cirrus_vga_info = { .class_init = isa_cirrus_vga_class_init, }; -static void isa_cirrus_vga_register(void) -{ - type_register_static(&isa_cirrus_vga_info); -} -device_init(isa_cirrus_vga_register) - /*************************************** * * PCI bus support @@ -2996,8 +2990,10 @@ static TypeInfo cirrus_vga_info = { .class_init = cirrus_vga_class_init, }; -static void cirrus_vga_register(void) +static void cirrus_vga_register_types(void) { + type_register_static(&isa_cirrus_vga_info); type_register_static(&cirrus_vga_info); } -device_init(cirrus_vga_register); + +type_init(cirrus_vga_register_types) diff --git a/hw/cs4231.c b/hw/cs4231.c index c0badbf..cfec1d9 100644 --- a/hw/cs4231.c +++ b/hw/cs4231.c @@ -173,9 +173,9 @@ static TypeInfo cs4231_info = { .class_init = cs4231_class_init, }; -static void cs4231_register_devices(void) +static void cs4231_register_types(void) { type_register_static(&cs4231_info); } -device_init(cs4231_register_devices) +type_init(cs4231_register_types) diff --git a/hw/cs4231a.c b/hw/cs4231a.c index ad04ad6..e07b9d6 100644 --- a/hw/cs4231a.c +++ b/hw/cs4231a.c @@ -689,8 +689,9 @@ static TypeInfo cs4231a_info = { .class_init = cs4231a_class_initfn, }; -static void cs4231a_register (void) +static void cs4231a_register_types (void) { type_register_static (&cs4231a_info); } -device_init (cs4231a_register) + +type_init (cs4231a_register_types) diff --git a/hw/debugcon.c b/hw/debugcon.c index 3903b26..14ab326 100644 --- a/hw/debugcon.c +++ b/hw/debugcon.c @@ -109,9 +109,9 @@ static TypeInfo debugcon_isa_info = { .class_init = debugcon_isa_class_initfn, }; -static void debugcon_register_devices(void) +static void debugcon_register_types(void) { type_register_static(&debugcon_isa_info); } -device_init(debugcon_register_devices) +type_init(debugcon_register_types) diff --git a/hw/dec_pci.c b/hw/dec_pci.c index a40fbcf..37337bf 100644 --- a/hw/dec_pci.c +++ b/hw/dec_pci.c @@ -140,11 +140,11 @@ static TypeInfo pci_dec_21154_device_info = { .class_init = pci_dec_21154_device_class_init, }; -static void dec_register_devices(void) +static void dec_register_types(void) { type_register_static(&pci_dec_21154_device_info); type_register_static(&dec_21154_pci_host_info); type_register_static(&dec_21154_pci_bridge_info); } -device_init(dec_register_devices) +type_init(dec_register_types) diff --git a/hw/ds1225y.c b/hw/ds1225y.c index 539bceb..2cd355b 100644 --- a/hw/ds1225y.c +++ b/hw/ds1225y.c @@ -157,9 +157,9 @@ static TypeInfo nvram_sysbus_info = { .class_init = nvram_sysbus_class_init, }; -static void nvram_register(void) +static void nvram_register_types(void) { type_register_static(&nvram_sysbus_info); } -device_init(nvram_register) +type_init(nvram_register_types) diff --git a/hw/ds1338.c b/hw/ds1338.c index b137e13..6397f0a 100644 --- a/hw/ds1338.c +++ b/hw/ds1338.c @@ -135,9 +135,9 @@ static TypeInfo ds1338_info = { .class_init = ds1338_class_init, }; -static void ds1338_register_devices(void) +static void ds1338_register_types(void) { type_register_static(&ds1338_info); } -device_init(ds1338_register_devices) +type_init(ds1338_register_types) @@ -1227,9 +1227,9 @@ static TypeInfo e1000_info = { .class_init = e1000_class_init, }; -static void e1000_register_devices(void) +static void e1000_register_types(void) { type_register_static(&e1000_info); } -device_init(e1000_register_devices) +type_init(e1000_register_types) diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c index 1cf2090..fe1cd90 100644 --- a/hw/eccmemctl.c +++ b/hw/eccmemctl.c @@ -332,9 +332,9 @@ static TypeInfo ecc_info = { }; -static void ecc_register_devices(void) +static void ecc_register_types(void) { type_register_static(&ecc_info); } -device_init(ecc_register_devices) +type_init(ecc_register_types) diff --git a/hw/eepro100.c b/hw/eepro100.c index 843610c..e3ba719 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -2089,7 +2089,7 @@ static void eepro100_class_init(ObjectClass *klass, void *data) k->subsystem_id = info->subsystem_id; } -static void eepro100_register_devices(void) +static void eepro100_register_types(void) { size_t i; for (i = 0; i < ARRAY_SIZE(e100_devices); i++) { @@ -2105,4 +2105,4 @@ static void eepro100_register_devices(void) } } -device_init(eepro100_register_devices) +type_init(eepro100_register_types) diff --git a/hw/empty_slot.c b/hw/empty_slot.c index 1bc1815..099c85e 100644 --- a/hw/empty_slot.c +++ b/hw/empty_slot.c @@ -90,9 +90,9 @@ static TypeInfo empty_slot_info = { .class_init = empty_slot_class_init, }; -static void empty_slot_register_devices(void) +static void empty_slot_register_types(void) { type_register_static(&empty_slot_info); } -device_init(empty_slot_register_devices); +type_init(empty_slot_register_types) diff --git a/hw/es1370.c b/hw/es1370.c index e377c48..f19cef3 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -1054,9 +1054,10 @@ static TypeInfo es1370_info = { .class_init = es1370_class_init, }; -static void es1370_register (void) +static void es1370_register_types (void) { type_register_static (&es1370_info); } -device_init (es1370_register); + +type_init (es1370_register_types) @@ -931,9 +931,9 @@ static TypeInfo escc_info = { .class_init = escc_class_init, }; -static void escc_register_devices(void) +static void escc_register_types(void) { type_register_static(&escc_info); } -device_init(escc_register_devices) +type_init(escc_register_types) @@ -775,9 +775,9 @@ static TypeInfo esp_info = { .class_init = esp_class_init, }; -static void esp_register_devices(void) +static void esp_register_types(void) { type_register_static(&esp_info); } -device_init(esp_register_devices) +type_init(esp_register_types) diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index aefd577..16a0637 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -637,9 +637,9 @@ static TypeInfo etraxfs_eth_info = { .class_init = etraxfs_eth_class_init, }; -static void etraxfs_eth_register(void) +static void etraxfs_eth_register_types(void) { type_register_static(&etraxfs_eth_info); } -device_init(etraxfs_eth_register) +type_init(etraxfs_eth_register_types) diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 33541fc..dc27f88 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -172,9 +172,9 @@ static TypeInfo etraxfs_pic_info = { .class_init = etraxfs_pic_class_init, }; -static void etraxfs_pic_register(void) +static void etraxfs_pic_register_types(void) { type_register_static(&etraxfs_pic_info); } -device_init(etraxfs_pic_register) +type_init(etraxfs_pic_register_types) diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c index 567cb8c..cecd819 100644 --- a/hw/etraxfs_ser.c +++ b/hw/etraxfs_ser.c @@ -240,9 +240,9 @@ static TypeInfo etraxfs_ser_info = { .class_init = etraxfs_ser_class_init, }; -static void etraxfs_serial_register(void) +static void etraxfs_serial_register_types(void) { type_register_static(&etraxfs_ser_info); } -device_init(etraxfs_serial_register) +type_init(etraxfs_serial_register_types) diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c index b71c5ee..9076a49 100644 --- a/hw/etraxfs_timer.c +++ b/hw/etraxfs_timer.c @@ -343,9 +343,9 @@ static TypeInfo etraxfs_timer_info = { .class_init = etraxfs_timer_class_init, }; -static void etraxfs_timer_register(void) +static void etraxfs_timer_register_types(void) { type_register_static(&etraxfs_timer_info); } -device_init(etraxfs_timer_register) +type_init(etraxfs_timer_register_types) @@ -2043,11 +2043,11 @@ static TypeInfo sun4m_fdc_info = { .class_init = sun4m_fdc_class_init, }; -static void fdc_register_devices(void) +static void fdc_register_types(void) { type_register_static(&isa_fdc_info); type_register_static(&sysbus_fdc_info); type_register_static(&sun4m_fdc_info); } -device_init(fdc_register_devices) +type_init(fdc_register_types) diff --git a/hw/framebuffer.c b/hw/framebuffer.c index ea122fb..f4747cd 100644 --- a/hw/framebuffer.c +++ b/hw/framebuffer.c @@ -87,7 +87,7 @@ void framebuffer_update_display( dest += i * dest_row_pitch; for (; i < rows; i++) { - dirty = memory_region_get_dirty(mem, addr, addr + src_width, + dirty = memory_region_get_dirty(mem, addr, src_width, DIRTY_MEMORY_VGA); if (dirty || invalidate) { fn(opaque, dest, src, cols, dest_col_pitch); diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 6b2f7d1..7b3b576 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -556,9 +556,9 @@ static TypeInfo fw_cfg_info = { .class_init = fw_cfg_class_init, }; -static void fw_cfg_register_devices(void) +static void fw_cfg_register_types(void) { type_register_static(&fw_cfg_info); } -device_init(fw_cfg_register_devices) +type_init(fw_cfg_register_types) diff --git a/hw/g364fb.c b/hw/g364fb.c index 66d0044..9c63bdd 100644 --- a/hw/g364fb.c +++ b/hw/g364fb.c @@ -574,9 +574,9 @@ static TypeInfo g364fb_sysbus_info = { .class_init = g364fb_sysbus_class_init, }; -static void g364fb_register(void) +static void g364fb_register_types(void) { type_register_static(&g364fb_sysbus_info); } -device_init(g364fb_register); +type_init(g364fb_register_types) diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index 8122baf..81ff3a3 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -157,10 +157,10 @@ static TypeInfo grackle_pci_host_info = { .class_init = pci_grackle_class_init, }; -static void grackle_register_devices(void) +static void grackle_register_types(void) { type_register_static(&grackle_pci_info); type_register_static(&grackle_pci_host_info); } -device_init(grackle_register_devices) +type_init(grackle_register_types) diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c index 89de2d8..73fc989 100644 --- a/hw/grlib_apbuart.c +++ b/hw/grlib_apbuart.c @@ -263,9 +263,9 @@ static TypeInfo grlib_gptimer_info = { .class_init = grlib_gptimer_class_init, }; -static void grlib_gptimer_register(void) +static void grlib_gptimer_register_types(void) { type_register_static(&grlib_gptimer_info); } -device_init(grlib_gptimer_register) +type_init(grlib_gptimer_register_types) diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c index fb0b236..41770a9 100644 --- a/hw/grlib_gptimer.c +++ b/hw/grlib_gptimer.c @@ -396,9 +396,9 @@ static TypeInfo grlib_gptimer_info = { .class_init = grlib_gptimer_class_init, }; -static void grlib_gptimer_register(void) +static void grlib_gptimer_register_types(void) { type_register_static(&grlib_gptimer_info); } -device_init(grlib_gptimer_register) +type_init(grlib_gptimer_register_types) diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c index 1e5ad82..0f6e65c 100644 --- a/hw/grlib_irqmp.c +++ b/hw/grlib_irqmp.c @@ -377,9 +377,9 @@ static TypeInfo grlib_irqmp_info = { .class_init = grlib_irqmp_class_init, }; -static void grlib_irqmp_register(void) +static void grlib_irqmp_register_types(void) { type_register_static(&grlib_irqmp_info); } -device_init(grlib_irqmp_register) +type_init(grlib_irqmp_register_types) diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index e8cd59c..a2d0e5a 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -1168,10 +1168,10 @@ static TypeInfo gt64120_info = { .class_init = gt64120_class_init, }; -static void gt64120_pci_register_devices(void) +static void gt64120_pci_register_types(void) { type_register_static(>64120_info); type_register_static(>64120_pci_info); } -device_init(gt64120_pci_register_devices) +type_init(gt64120_pci_register_types) @@ -324,8 +324,9 @@ static TypeInfo gus_info = { .class_init = gus_class_initfn, }; -static void gus_register (void) +static void gus_register_types (void) { type_register_static (&gus_info); } -device_init (gus_register) + +type_init (gus_register_types) diff --git a/hw/hda-audio.c b/hw/hda-audio.c index 152f8e6..8995519 100644 --- a/hw/hda-audio.c +++ b/hw/hda-audio.c @@ -948,9 +948,10 @@ static TypeInfo hda_audio_duplex_info = { .class_init = hda_audio_duplex_class_init, }; -static void hda_audio_register(void) +static void hda_audio_register_types(void) { type_register_static(&hda_audio_output_info); type_register_static(&hda_audio_duplex_info); } -device_init(hda_audio_register); + +type_init(hda_audio_register_types) diff --git a/hw/highbank.c b/hw/highbank.c index 684178e..b28b464 100644 --- a/hw/highbank.c +++ b/hw/highbank.c @@ -177,12 +177,12 @@ static TypeInfo highbank_regs_info = { .class_init = highbank_regs_class_init, }; -static void highbank_regs_register_device(void) +static void highbank_regs_register_types(void) { type_register_static(&highbank_regs_info); } -device_init(highbank_regs_register_device) +type_init(highbank_regs_register_types) static struct arm_boot_info highbank_binfo; @@ -720,9 +720,9 @@ static TypeInfo hpet_device_info = { .class_init = hpet_device_class_init, }; -static void hpet_register_device(void) +static void hpet_register_types(void) { type_register_static(&hpet_device_info); } -device_init(hpet_register_device) +type_init(hpet_register_types) @@ -230,9 +230,9 @@ static TypeInfo i2c_slave_type_info = { .class_init = i2c_slave_class_init, }; -static void i2c_slave_register_devices(void) +static void i2c_slave_register_types(void) { type_register_static(&i2c_slave_type_info); } -device_init(i2c_slave_register_devices); +type_init(i2c_slave_register_types) diff --git a/hw/i82374.c b/hw/i82374.c index 220e8cc..67298a3 100644 --- a/hw/i82374.c +++ b/hw/i82374.c @@ -157,9 +157,9 @@ static TypeInfo i82374_isa_info = { .class_init = i82374_class_init, }; -static void i82374_register_devices(void) +static void i82374_register_types(void) { type_register_static(&i82374_isa_info); } -device_init(i82374_register_devices) +type_init(i82374_register_types) diff --git a/hw/i82378.c b/hw/i82378.c index 9c3efe8..3929c04 100644 --- a/hw/i82378.c +++ b/hw/i82378.c @@ -267,9 +267,9 @@ static TypeInfo pci_i82378_info = { .class_init = pci_i82378_class_init, }; -static void i82378_register_devices(void) +static void i82378_register_types(void) { type_register_static(&pci_i82378_info); } -device_init(i82378_register_devices) +type_init(i82378_register_types) @@ -559,8 +559,9 @@ static TypeInfo pit_info = { .class_init = pit_class_initfn, }; -static void pit_register(void) +static void pit_register_types(void) { type_register_static(&pit_info); } -device_init(pit_register) + +type_init(pit_register_types) @@ -488,9 +488,9 @@ static TypeInfo i8259_info = { .class_init = i8259_class_init, }; -static void pic_register(void) +static void pic_register_types(void) { type_register_static(&i8259_info); } -device_init(pic_register) +type_init(pic_register_types) diff --git a/hw/i8259_common.c b/hw/i8259_common.c index 9f150bc..775fda4 100644 --- a/hw/i8259_common.c +++ b/hw/i8259_common.c @@ -153,9 +153,9 @@ static TypeInfo pic_common_type = { .abstract = true, }; -static void register_devices(void) +static void register_types(void) { type_register_static(&pic_common_type); } -device_init(register_devices); +type_init(register_types); diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index c87a6ca..b515f41 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -146,6 +146,7 @@ static void ahci_check_irq(AHCIState *s) DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus); + s->control_regs.irqstatus = 0; for (i = 0; i < s->ports; i++) { AHCIPortRegs *pr = &s->dev[i].port_regs; if (pr->irq_stat & pr->irq_mask) { @@ -216,6 +217,7 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) break; case PORT_IRQ_STAT: pr->irq_stat &= ~val; + ahci_check_irq(s); break; case PORT_IRQ_MASK: pr->irq_mask = val & 0xfdc000ff; @@ -560,6 +562,11 @@ static void ahci_reset_port(AHCIState *s, int port) ncq_tfs->aiocb = NULL; } + /* Maybe we just finished the request thanks to bdrv_aio_cancel() */ + if (!ncq_tfs->used) { + continue; + } + qemu_sglist_destroy(&ncq_tfs->sglist); ncq_tfs->used = 0; } @@ -1261,9 +1268,9 @@ static TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, }; -static void sysbus_ahci_register(void) +static void sysbus_ahci_register_types(void) { type_register_static(&sysbus_ahci_info); } -device_init(sysbus_ahci_register); +type_init(sysbus_ahci_register_types) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index a119500..743ec02 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -351,8 +351,9 @@ static TypeInfo cmd646_ide_info = { .class_init = cmd646_ide_class_init, }; -static void cmd646_ide_register(void) +static void cmd646_ide_register_types(void) { type_register_static(&cmd646_ide_info); } -device_init(cmd646_ide_register); + +type_init(cmd646_ide_register_types) diff --git a/hw/ide/ich.c b/hw/ide/ich.c index 5cdaa99..560ae37 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -168,8 +168,9 @@ static TypeInfo ich_ahci_info = { .class_init = ich_ahci_class_init, }; -static void ich_ahci_register(void) +static void ich_ahci_register_types(void) { type_register_static(&ich_ahci_info); } -device_init(ich_ahci_register); + +type_init(ich_ahci_register_types) diff --git a/hw/ide/isa.c b/hw/ide/isa.c index a0bcb43..8ab2718 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -118,9 +118,9 @@ static TypeInfo isa_ide_info = { .class_init = isa_ide_class_initfn, }; -static void isa_ide_register_devices(void) +static void isa_ide_register_types(void) { type_register_static(&isa_ide_info); } -device_init(isa_ide_register_devices) +type_init(isa_ide_register_types) diff --git a/hw/ide/piix.c b/hw/ide/piix.c index bf4465b..aee60aa 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -299,10 +299,11 @@ static TypeInfo piix4_ide_info = { .class_init = piix4_ide_class_init, }; -static void piix_ide_register(void) +static void piix_ide_register_types(void) { type_register_static(&piix3_ide_info); type_register_static(&piix3_ide_xen_info); type_register_static(&piix4_ide_info); } -device_init(piix_ide_register); + +type_init(piix_ide_register_types) diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 1640616..f6a4896 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -257,11 +257,12 @@ static TypeInfo ide_device_type_info = { .class_init = ide_device_class_init, }; -static void ide_dev_register(void) +static void ide_register_types(void) { type_register_static(&ide_hd_info); type_register_static(&ide_cd_info); type_register_static(&ide_drive_info); type_register_static(&ide_device_type_info); } -device_init(ide_dev_register); + +type_init(ide_register_types) diff --git a/hw/ide/via.c b/hw/ide/via.c index b4ca6f2..2886bc6 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -234,8 +234,9 @@ static TypeInfo via_ide_info = { .class_init = via_ide_class_init, }; -static void via_ide_register(void) +static void via_ide_register_types(void) { type_register_static(&via_ide_info); } -device_init(via_ide_register); + +type_init(via_ide_register_types) diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 6dbd649..294d7da 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -553,10 +553,10 @@ static TypeInfo icp_pic_info = { .class_init = icp_pic_class_init, }; -static void integratorcp_register_devices(void) +static void integratorcp_register_types(void) { type_register_static(&icp_pic_info); type_register_static(&core_info); } -device_init(integratorcp_register_devices) +type_init(integratorcp_register_types) diff --git a/hw/intel-hda.c b/hw/intel-hda.c index 83c42d5..bb11af2 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -1287,12 +1287,13 @@ static TypeInfo hda_codec_device_type_info = { .class_init = hda_codec_device_class_init, }; -static void intel_hda_register(void) +static void intel_hda_register_types(void) { type_register_static(&intel_hda_info); type_register_static(&hda_codec_device_type_info); } -device_init(intel_hda_register); + +type_init(intel_hda_register_types) /* * create intel hda controller with codec attached to it, diff --git a/hw/ioapic.c b/hw/ioapic.c index 79549f8..3fee011 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -251,9 +251,9 @@ static TypeInfo ioapic_info = { .class_init = ioapic_class_init, }; -static void ioapic_register_devices(void) +static void ioapic_register_types(void) { type_register_static(&ioapic_info); } -device_init(ioapic_register_devices) +type_init(ioapic_register_types) diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c index f932700..653eef2 100644 --- a/hw/ioapic_common.c +++ b/hw/ioapic_common.c @@ -112,10 +112,9 @@ static TypeInfo ioapic_common_type = { .abstract = true, }; -static void register_devices(void) +static void register_types(void) { type_register_static(&ioapic_common_type); } -device_init(register_devices); - +type_init(register_types) diff --git a/hw/ioh3420.c b/hw/ioh3420.c index 1c60123..1632d31 100644 --- a/hw/ioh3420.c +++ b/hw/ioh3420.c @@ -237,12 +237,12 @@ static TypeInfo ioh3420_info = { .class_init = ioh3420_class_init, }; -static void ioh3420_register(void) +static void ioh3420_register_types(void) { type_register_static(&ioh3420_info); } -device_init(ioh3420_register); +type_init(ioh3420_register_types) /* * Local variables: diff --git a/hw/isa-bus.c b/hw/isa-bus.c index d03f828..5a43f03 100644 --- a/hw/isa-bus.c +++ b/hw/isa-bus.c @@ -210,7 +210,7 @@ static TypeInfo isa_device_type_info = { .class_init = isa_device_class_init, }; -static void isabus_register_devices(void) +static void isabus_register_types(void) { type_register_static(&isabus_bridge_info); type_register_static(&isa_device_type_info); @@ -235,4 +235,4 @@ MemoryRegion *isa_address_space(ISADevice *dev) return get_system_memory(); } -device_init(isabus_register_devices) +type_init(isabus_register_types) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 6f017d4..64e1cd9 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -798,9 +798,9 @@ static TypeInfo ivshmem_info = { .class_init = ivshmem_class_init, }; -static void ivshmem_register_devices(void) +static void ivshmem_register_types(void) { type_register_static(&ivshmem_info); } -device_init(ivshmem_register_devices) +type_init(ivshmem_register_types) diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c index dfc2ab3..5bb0a4b 100644 --- a/hw/kvm/apic.c +++ b/hw/kvm/apic.c @@ -139,9 +139,9 @@ static TypeInfo kvm_apic_info = { .class_init = kvm_apic_class_init, }; -static void kvm_apic_register_device(void) +static void kvm_apic_register_types(void) { type_register_static(&kvm_apic_info); } -device_init(kvm_apic_register_device) +type_init(kvm_apic_register_types) diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c index d5a5386..2157340 100644 --- a/hw/kvm/clock.c +++ b/hw/kvm/clock.c @@ -119,11 +119,11 @@ void kvmclock_create(void) } } -static void kvmclock_register_device(void) +static void kvmclock_register_types(void) { if (kvm_enabled()) { type_register_static(&kvmclock_info); } } -device_init(kvmclock_register_device); +type_init(kvmclock_register_types) diff --git a/hw/kvm/i8259.c b/hw/kvm/i8259.c index 14bd427..eb98889 100644 --- a/hw/kvm/i8259.c +++ b/hw/kvm/i8259.c @@ -130,9 +130,9 @@ static TypeInfo kvm_i8259_info = { .class_init = kvm_i8259_class_init, }; -static void kvm_pic_register(void) +static void kvm_pic_register_types(void) { type_register_static(&kvm_i8259_info); } -device_init(kvm_pic_register) +type_init(kvm_pic_register_types) diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c index b316933..3ae3175 100644 --- a/hw/kvm/ioapic.c +++ b/hw/kvm/ioapic.c @@ -117,9 +117,9 @@ static TypeInfo kvm_ioapic_info = { .class_init = kvm_ioapic_class_init, }; -static void kvm_ioapic_register_device(void) +static void kvm_ioapic_register_types(void) { type_register_static(&kvm_ioapic_info); } -device_init(kvm_ioapic_register_device) +type_init(kvm_ioapic_register_types) diff --git a/hw/lan9118.c b/hw/lan9118.c index 78777c7..aeb0c39 100644 --- a/hw/lan9118.c +++ b/hw/lan9118.c @@ -1261,7 +1261,7 @@ static TypeInfo lan9118_info = { .class_init = lan9118_class_init, }; -static void lan9118_register_devices(void) +static void lan9118_register_types(void) { type_register_static(&lan9118_info); } @@ -1282,4 +1282,4 @@ void lan9118_init(NICInfo *nd, uint32_t base, qemu_irq irq) sysbus_connect_irq(s, 0, irq); } -device_init(lan9118_register_devices) +type_init(lan9118_register_types) @@ -162,8 +162,9 @@ static TypeInfo lance_info = { .class_init = lance_class_init, }; -static void lance_register_devices(void) +static void lance_register_types(void) { type_register_static(&lance_info); } -device_init(lance_register_devices) + +type_init(lance_register_types) diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c index 38dd282..f07ed39 100644 --- a/hw/lm32_juart.c +++ b/hw/lm32_juart.c @@ -151,9 +151,9 @@ static TypeInfo lm32_juart_info = { .class_init = lm32_juart_class_init, }; -static void lm32_juart_register(void) +static void lm32_juart_register_types(void) { type_register_static(&lm32_juart_info); } -device_init(lm32_juart_register) +type_init(lm32_juart_register_types) diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c index 7be6d0d..32f65db 100644 --- a/hw/lm32_pic.c +++ b/hw/lm32_pic.c @@ -191,9 +191,9 @@ static TypeInfo lm32_pic_info = { .class_init = lm32_pic_class_init, }; -static void lm32_pic_register(void) +static void lm32_pic_register_types(void) { type_register_static(&lm32_pic_info); } -device_init(lm32_pic_register) +type_init(lm32_pic_register_types) diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c index ba6f4ac..bbe03c4 100644 --- a/hw/lm32_sys.c +++ b/hw/lm32_sys.c @@ -164,9 +164,9 @@ static TypeInfo lm32_sys_info = { .class_init = lm32_sys_class_init, }; -static void lm32_sys_register(void) +static void lm32_sys_register_types(void) { type_register_static(&lm32_sys_info); } -device_init(lm32_sys_register) +type_init(lm32_sys_register_types) diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c index 3cb4e0a..e9450a0 100644 --- a/hw/lm32_timer.c +++ b/hw/lm32_timer.c @@ -222,9 +222,9 @@ static TypeInfo lm32_timer_info = { .class_init = lm32_timer_class_init, }; -static void lm32_timer_register(void) +static void lm32_timer_register_types(void) { type_register_static(&lm32_timer_info); } -device_init(lm32_timer_register) +type_init(lm32_timer_register_types) diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c index 630ccb7..57066e2 100644 --- a/hw/lm32_uart.c +++ b/hw/lm32_uart.c @@ -288,9 +288,9 @@ static TypeInfo lm32_uart_info = { .class_init = lm32_uart_class_init, }; -static void lm32_uart_register(void) +static void lm32_uart_register_types(void) { type_register_static(&lm32_uart_info); } -device_init(lm32_uart_register) +type_init(lm32_uart_register_types) diff --git a/hw/lm832x.c b/hw/lm832x.c index 895d306..8e09f9b 100644 --- a/hw/lm832x.c +++ b/hw/lm832x.c @@ -513,9 +513,9 @@ static TypeInfo lm8323_info = { .class_init = lm8323_class_init, }; -static void lm832x_register_devices(void) +static void lm832x_register_types(void) { type_register_static(&lm8323_info); } -device_init(lm832x_register_devices) +type_init(lm832x_register_types) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 9a7ffe3..0acd1d0 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -2142,9 +2142,9 @@ static TypeInfo lsi_info = { .class_init = lsi_class_init, }; -static void lsi53c895a_register_devices(void) +static void lsi53c895a_register_types(void) { type_register_static(&lsi_info); } -device_init(lsi53c895a_register_devices); +type_init(lsi53c895a_register_types) diff --git a/hw/m48t59.c b/hw/m48t59.c index c35867d..60bbb00 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -768,10 +768,10 @@ static TypeInfo m48t59_info = { .class_init = m48t59_class_init, }; -static void m48t59_register_devices(void) +static void m48t59_register_types(void) { type_register_static(&m48t59_info); type_register_static(&m48t59_isa_info); } -device_init(m48t59_register_devices) +type_init(m48t59_register_types) @@ -97,12 +97,12 @@ static TypeInfo macio_info = { .class_init = macio_class_init, }; -static void macio_register(void) +static void macio_register_types(void) { type_register_static(&macio_info); } -device_init(macio_register); +type_init(macio_register_types) void macio_init (PCIBus *bus, int device_id, int is_oldworld, MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c index b628f17..f6f1937 100644 --- a/hw/marvell_88w8618_audio.c +++ b/hw/marvell_88w8618_audio.c @@ -295,9 +295,9 @@ static TypeInfo mv88w8618_audio_info = { .class_init = mv88w8618_audio_class_init, }; -static void mv88w8618_register_devices(void) +static void mv88w8618_register_types(void) { type_register_static(&mv88w8618_audio_info); } -device_init(mv88w8618_register_devices) +type_init(mv88w8618_register_types) diff --git a/hw/max111x.c b/hw/max111x.c index 9d61aa9..706d89f 100644 --- a/hw/max111x.c +++ b/hw/max111x.c @@ -183,10 +183,10 @@ static TypeInfo max1111_info = { .class_init = max1111_class_init, }; -static void max111x_register_devices(void) +static void max111x_register_types(void) { type_register_static(&max1110_info); type_register_static(&max1111_info); } -device_init(max111x_register_devices) +type_init(max111x_register_types) diff --git a/hw/max7310.c b/hw/max7310.c index 3a6bb96..1ed18ba 100644 --- a/hw/max7310.c +++ b/hw/max7310.c @@ -205,9 +205,9 @@ static TypeInfo max7310_info = { .class_init = max7310_class_init, }; -static void max7310_register_devices(void) +static void max7310_register_types(void) { type_register_static(&max7310_info); } -device_init(max7310_register_devices) +type_init(max7310_register_types) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 4a43225..6c1ad38 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -733,8 +733,9 @@ static TypeInfo mc146818rtc_info = { .class_init = rtc_class_initfn, }; -static void mc146818rtc_register(void) +static void mc146818rtc_register_types(void) { type_register_static(&mc146818rtc_info); } -device_init(mc146818rtc_register) + +type_init(mc146818rtc_register_types) diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c index 0881643..4414f39 100644 --- a/hw/milkymist-ac97.c +++ b/hw/milkymist-ac97.c @@ -336,9 +336,9 @@ static TypeInfo milkymist_ac97_info = { .class_init = milkymist_ac97_class_init, }; -static void milkymist_ac97_register(void) +static void milkymist_ac97_register_types(void) { type_register_static(&milkymist_ac97_info); } -device_init(milkymist_ac97_register) +type_init(milkymist_ac97_register_types) diff --git a/hw/milkymist-hpdmc.c b/hw/milkymist-hpdmc.c index b5122af..2da0293 100644 --- a/hw/milkymist-hpdmc.c +++ b/hw/milkymist-hpdmc.c @@ -162,9 +162,9 @@ static TypeInfo milkymist_hpdmc_info = { .class_init = milkymist_hpdmc_class_init, }; -static void milkymist_hpdmc_register(void) +static void milkymist_hpdmc_register_types(void) { type_register_static(&milkymist_hpdmc_info); } -device_init(milkymist_hpdmc_register) +type_init(milkymist_hpdmc_register_types) diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c index 3c1c68a..3515c3c 100644 --- a/hw/milkymist-memcard.c +++ b/hw/milkymist-memcard.c @@ -295,9 +295,9 @@ static TypeInfo milkymist_memcard_info = { .class_init = milkymist_memcard_class_init, }; -static void milkymist_memcard_register(void) +static void milkymist_memcard_register_types(void) { type_register_static(&milkymist_memcard_info); } -device_init(milkymist_memcard_register) +type_init(milkymist_memcard_register_types) diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c index b9b553f..70bf336 100644 --- a/hw/milkymist-minimac2.c +++ b/hw/milkymist-minimac2.c @@ -542,9 +542,9 @@ static TypeInfo milkymist_minimac2_info = { .class_init = milkymist_minimac2_class_init, }; -static void milkymist_minimac2_register(void) +static void milkymist_minimac2_register_types(void) { type_register_static(&milkymist_minimac2_info); } -device_init(milkymist_minimac2_register) +type_init(milkymist_minimac2_register_types) diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c index 1b73a46..0f9ff4a 100644 --- a/hw/milkymist-pfpu.c +++ b/hw/milkymist-pfpu.c @@ -536,9 +536,9 @@ static TypeInfo milkymist_pfpu_info = { .class_init = milkymist_pfpu_class_init, }; -static void milkymist_pfpu_register(void) +static void milkymist_pfpu_register_types(void) { type_register_static(&milkymist_pfpu_info); } -device_init(milkymist_pfpu_register) +type_init(milkymist_pfpu_register_types) diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c index 5d496cb..ecc2be9 100644 --- a/hw/milkymist-softusb.c +++ b/hw/milkymist-softusb.c @@ -323,9 +323,9 @@ static TypeInfo milkymist_softusb_info = { .class_init = milkymist_softusb_class_init, }; -static void milkymist_softusb_register(void) +static void milkymist_softusb_register_types(void) { type_register_static(&milkymist_softusb_info); } -device_init(milkymist_softusb_register) +type_init(milkymist_softusb_register_types) diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c index 18171f6..a88548e 100644 --- a/hw/milkymist-sysctl.c +++ b/hw/milkymist-sysctl.c @@ -322,9 +322,9 @@ static TypeInfo milkymist_sysctl_info = { .class_init = milkymist_sysctl_class_init, }; -static void milkymist_sysctl_register(void) +static void milkymist_sysctl_register_types(void) { type_register_static(&milkymist_sysctl_info); } -device_init(milkymist_sysctl_register) +type_init(milkymist_sysctl_register_types) diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c index 474eae0..210ceed 100644 --- a/hw/milkymist-tmu2.c +++ b/hw/milkymist-tmu2.c @@ -482,9 +482,9 @@ static TypeInfo milkymist_tmu2_info = { .class_init = milkymist_tmu2_class_init, }; -static void milkymist_tmu2_register(void) +static void milkymist_tmu2_register_types(void) { type_register_static(&milkymist_tmu2_info); } -device_init(milkymist_tmu2_register) +type_init(milkymist_tmu2_register_types) diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c index f9a229c..291fe3c 100644 --- a/hw/milkymist-uart.c +++ b/hw/milkymist-uart.c @@ -235,9 +235,9 @@ static TypeInfo milkymist_uart_info = { .class_init = milkymist_uart_class_init, }; -static void milkymist_uart_register(void) +static void milkymist_uart_register_types(void) { type_register_static(&milkymist_uart_info); } -device_init(milkymist_uart_register) +type_init(milkymist_uart_register_types) diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c index 92ad02f..69afd72 100644 --- a/hw/milkymist-vgafb.c +++ b/hw/milkymist-vgafb.c @@ -323,9 +323,9 @@ static TypeInfo milkymist_vgafb_info = { .class_init = milkymist_vgafb_class_init, }; -static void milkymist_vgafb_register(void) +static void milkymist_vgafb_register_types(void) { type_register_static(&milkymist_vgafb_info); } -device_init(milkymist_vgafb_register) +type_init(milkymist_vgafb_register_types) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index d232630..ffecefd 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -1029,7 +1029,7 @@ static QEMUMachine mips_malta_machine = { .is_default = 1, }; -static void mips_malta_device_init(void) +static void mips_malta_register_types(void) { type_register_static(&mips_malta_device); } @@ -1039,5 +1039,5 @@ static void mips_malta_machine_init(void) qemu_register_machine(&mips_malta_machine); } -device_init(mips_malta_device_init); +type_init(mips_malta_register_types) machine_init(mips_malta_machine_init); diff --git a/hw/mipsnet.c b/hw/mipsnet.c index a0e6c9f..50d92f8 100644 --- a/hw/mipsnet.c +++ b/hw/mipsnet.c @@ -276,9 +276,9 @@ static TypeInfo mipsnet_info = { .class_init = mipsnet_class_init, }; -static void mipsnet_register_devices(void) +static void mipsnet_register_types(void) { type_register_static(&mipsnet_info); } -device_init(mipsnet_register_devices) +type_init(mipsnet_register_types) diff --git a/hw/mpc8544_guts.c b/hw/mpc8544_guts.c index 28cd60d..aeb2de7 100644 --- a/hw/mpc8544_guts.c +++ b/hw/mpc8544_guts.c @@ -135,8 +135,9 @@ static TypeInfo mpc8544_guts_info = { .class_init = mpc8544_guts_class_init, }; -static void mpc8544_guts_register(void) +static void mpc8544_guts_register_types(void) { type_register_static(&mpc8544_guts_info); } -device_init(mpc8544_guts_register); + +type_init(mpc8544_guts_register_types) diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c index 1729db0..024192d 100644 --- a/hw/mst_fpga.c +++ b/hw/mst_fpga.c @@ -255,8 +255,9 @@ static TypeInfo mst_fpga_info = { .class_init = mst_fpga_class_init, }; -static void mst_fpga_register(void) +static void mst_fpga_register_types(void) { type_register_static(&mst_fpga_info); } -device_init(mst_fpga_register); + +type_init(mst_fpga_register_types) diff --git a/hw/musicpal.c b/hw/musicpal.c index ac90924..187a1ae 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1681,7 +1681,7 @@ static TypeInfo mv88w8618_wlan_info = { .class_init = mv88w8618_wlan_class_init, }; -static void musicpal_register_devices(void) +static void musicpal_register_types(void) { type_register_static(&mv88w8618_pic_info); type_register_static(&mv88w8618_pit_info); @@ -1693,4 +1693,4 @@ static void musicpal_register_devices(void) type_register_static(&musicpal_key_info); } -device_init(musicpal_register_devices) +type_init(musicpal_register_types) @@ -442,7 +442,7 @@ static TypeInfo nand_info = { .class_init = nand_class_init, }; -static void nand_create_device(void) +static void nand_register_types(void) { type_register_static(&nand_info); } @@ -635,7 +635,7 @@ DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id) return dev; } -device_init(nand_create_device) +type_init(nand_register_types) #else diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c index 1352282..a4a783a 100644 --- a/hw/ne2000-isa.c +++ b/hw/ne2000-isa.c @@ -104,9 +104,9 @@ static TypeInfo ne2000_isa_info = { .class_init = isa_ne2000_class_initfn, }; -static void ne2000_isa_register_devices(void) +static void ne2000_isa_register_types(void) { type_register_static(&ne2000_isa_info); } -device_init(ne2000_isa_register_devices) +type_init(ne2000_isa_register_types) diff --git a/hw/ne2000.c b/hw/ne2000.c index 080811e..bb84fd1 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -812,9 +812,9 @@ static TypeInfo ne2000_info = { .class_init = ne2000_class_init, }; -static void ne2000_register_devices(void) +static void ne2000_register_types(void) { type_register_static(&ne2000_info); } -device_init(ne2000_register_devices) +type_init(ne2000_register_types) diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c index 9a9a8e1..201ff77 100644 --- a/hw/omap_gpio.c +++ b/hw/omap_gpio.c @@ -783,10 +783,10 @@ static TypeInfo omap2_gpio_info = { .class_init = omap2_gpio_class_init, }; -static void omap_gpio_register_device(void) +static void omap_gpio_register_types(void) { type_register_static(&omap_gpio_info); type_register_static(&omap2_gpio_info); } -device_init(omap_gpio_register_device) +type_init(omap_gpio_register_types) diff --git a/hw/omap_intc.c b/hw/omap_intc.c index 5aa98a8..5076e07 100644 --- a/hw/omap_intc.c +++ b/hw/omap_intc.c @@ -640,10 +640,10 @@ static TypeInfo omap2_intc_info = { .class_init = omap2_intc_class_init, }; -static void omap_intc_register_device(void) +static void omap_intc_register_types(void) { type_register_static(&omap_intc_info); type_register_static(&omap2_intc_info); } -device_init(omap_intc_register_device) +type_init(omap_intc_register_types) diff --git a/hw/onenand.c b/hw/onenand.c index 8744b04..db6af68 100644 --- a/hw/onenand.c +++ b/hw/onenand.c @@ -828,7 +828,7 @@ static TypeInfo onenand_info = { .class_init = onenand_class_init, }; -static void onenand_register_device(void) +static void onenand_register_types(void) { type_register_static(&onenand_info); } @@ -838,4 +838,4 @@ void *onenand_raw_otp(DeviceState *onenand_device) return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp; } -device_init(onenand_register_device) +type_init(onenand_register_types) diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c index 09f2757..9b036cb 100644 --- a/hw/opencores_eth.c +++ b/hw/opencores_eth.c @@ -750,9 +750,9 @@ static TypeInfo open_eth_info = { .class_init = open_eth_class_init, }; -static void open_eth_register_devices(void) +static void open_eth_register_types(void) { type_register_static(&open_eth_info); } -device_init(open_eth_register_devices) +type_init(open_eth_register_types) diff --git a/hw/parallel.c b/hw/parallel.c index 484d727..219f384 100644 --- a/hw/parallel.c +++ b/hw/parallel.c @@ -606,9 +606,9 @@ static TypeInfo parallel_isa_info = { .class_init = parallel_isa_class_initfn, }; -static void parallel_register_devices(void) +static void parallel_register_types(void) { type_register_static(¶llel_isa_info); } -device_init(parallel_register_devices) +type_init(parallel_register_types) @@ -514,11 +514,12 @@ static TypeInfo port92_info = { .class_init = port92_class_initfn, }; -static void port92_register(void) +static void port92_register_types(void) { type_register_static(&port92_info); } -device_init(port92_register) + +type_init(port92_register_types) static void handle_a20_line_change(void *opaque, int irq, int level) { @@ -2003,9 +2003,9 @@ static TypeInfo pci_device_type_info = { .class_init = pci_device_class_init, }; -static void pci_register_devices(void) +static void pci_register_types(void) { type_register_static(&pci_device_type_info); } -device_init(pci_register_devices); +type_init(pci_register_types) @@ -513,8 +513,9 @@ static TypeInfo i8042_info = { .class_init = i8042_class_initfn, }; -static void i8042_register(void) +static void i8042_register_types(void) { type_register_static(&i8042_info); } -device_init(i8042_register) + +type_init(i8042_register_types) diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c index 439f32c..3682609 100644 --- a/hw/pcnet-pci.c +++ b/hw/pcnet-pci.c @@ -376,9 +376,9 @@ static TypeInfo pcnet_info = { .class_init = pcnet_class_init, }; -static void pci_pcnet_register_devices(void) +static void pci_pcnet_register_types(void) { type_register_static(&pcnet_info); } -device_init(pci_pcnet_register_devices) +type_init(pci_pcnet_register_types) diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index a9e88b9..2ca0fd4 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -102,6 +102,7 @@ static void pflash_setup_mappings(pflash_t *pfl) static void pflash_register_memory(pflash_t *pfl, int rom_mode) { memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode); + pfl->rom_mode = rom_mode; } static void pflash_timer (void *opaque) @@ -124,8 +124,9 @@ static TypeInfo piix4_info = { .class_init = piix4_class_init, }; -static void piix4_register(void) +static void piix4_register_types(void) { type_register_static(&piix4_info); } -device_init(piix4_register); + +type_init(piix4_register_types) diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 1906427..e0268fe 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -589,11 +589,12 @@ static TypeInfo i440fx_pcihost_info = { .class_init = i440fx_pcihost_class_init, }; -static void i440fx_register(void) +static void i440fx_register_types(void) { type_register_static(&i440fx_info); type_register_static(&piix3_info); type_register_static(&piix3_xen_info); type_register_static(&i440fx_pcihost_info); } -device_init(i440fx_register); + +type_init(i440fx_register_types) @@ -316,10 +316,10 @@ static TypeInfo pl011_luminary_info = { .class_init = pl011_luminary_class_init, }; -static void pl011_register_devices(void) +static void pl011_register_types(void) { type_register_static(&pl011_arm_info); type_register_static(&pl011_luminary_info); } -device_init(pl011_register_devices) +type_init(pl011_register_types) @@ -299,9 +299,9 @@ static TypeInfo pl022_info = { .class_init = pl022_class_init, }; -static void pl022_register_devices(void) +static void pl022_register_types(void) { type_register_static(&pl022_info); } -device_init(pl022_register_devices) +type_init(pl022_register_types) @@ -230,9 +230,9 @@ static TypeInfo pl031_info = { .class_init = pl031_class_init, }; -static void pl031_register_devices(void) +static void pl031_register_types(void) { type_register_static(&pl031_info); } -device_init(pl031_register_devices) +type_init(pl031_register_types) @@ -638,9 +638,9 @@ static TypeInfo pl041_device_info = { .class_init = pl041_device_class_init, }; -static void pl041_register_device(void) +static void pl041_register_types(void) { type_register_static(&pl041_device_info); } -device_init(pl041_register_device) +type_init(pl041_register_types) @@ -189,10 +189,10 @@ static TypeInfo pl050_mouse_info = { .class_init = pl050_mouse_class_init, }; -static void pl050_register_devices(void) +static void pl050_register_types(void) { type_register_static(&pl050_kbd_info); type_register_static(&pl050_mouse_info); } -device_init(pl050_register_devices) +type_init(pl050_register_types) @@ -325,10 +325,10 @@ static TypeInfo pl061_luminary_info = { .class_init = pl061_luminary_class_init, }; -static void pl061_register_devices(void) +static void pl061_register_types(void) { type_register_static(&pl061_info); type_register_static(&pl061_luminary_info); } -device_init(pl061_register_devices) +type_init(pl061_register_types) @@ -409,10 +409,10 @@ static TypeInfo pl081_info = { /* The PL080 and PL081 are the same except for the number of channels they implement (8 and 2 respectively). */ -static void pl080_register_devices(void) +static void pl080_register_types(void) { type_register_static(&pl080_info); type_register_static(&pl081_info); } -device_init(pl080_register_devices) +type_init(pl080_register_types) @@ -520,11 +520,11 @@ static TypeInfo pl111_info = { .class_init = pl111_class_init, }; -static void pl110_register_devices(void) +static void pl110_register_types(void) { type_register_static(&pl110_info); type_register_static(&pl110_versatile_info); type_register_static(&pl111_info); } -device_init(pl110_register_devices) +type_init(pl110_register_types) @@ -505,9 +505,9 @@ static TypeInfo pl181_info = { .class_init = pl181_class_init, }; -static void pl181_register_devices(void) +static void pl181_register_types(void) { type_register_static(&pl181_info); } -device_init(pl181_register_devices) +type_init(pl181_register_types) @@ -273,9 +273,9 @@ static TypeInfo pl190_info = { .class_init = pl190_class_init, }; -static void pl190_register_devices(void) +static void pl190_register_types(void) { type_register_static(&pl190_info); } -device_init(pl190_register_devices) +type_init(pl190_register_types) diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index d11f120..203c3cd 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -400,9 +400,10 @@ static TypeInfo ppc4xx_pcihost_info = { .class_init = ppc4xx_pcihost_class_init, }; -static void ppc4xx_pci_register(void) +static void ppc4xx_pci_register_types(void) { type_register_static(&ppc4xx_pcihost_info); type_register_static(&ppc4xx_host_bridge_info); } -device_init(ppc4xx_pci_register); + +type_init(ppc4xx_pci_register_types) diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index d5bce71..0f60b24 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -373,9 +373,10 @@ static TypeInfo e500_pcihost_info = { .class_init = e500_pcihost_class_init, }; -static void e500_pci_register(void) +static void e500_pci_register_types(void) { type_register_static(&e500_pcihost_info); type_register_static(&e500_host_bridge_info); } -device_init(e500_pci_register); + +type_init(e500_pci_register_types) diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index 9d648ec..6b8a189 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -217,8 +217,9 @@ static TypeInfo ppce500_spin_info = { .class_init = ppce500_spin_class_init, }; -static void ppce500_spin_register(void) +static void ppce500_spin_register_types(void) { type_register_static(&ppce500_spin_info); } -device_init(ppce500_spin_register); + +type_init(ppce500_spin_register_types) diff --git a/hw/prep_pci.c b/hw/prep_pci.c index 40b8bb0..8b29da9 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -173,10 +173,10 @@ static TypeInfo raven_pcihost_info = { .class_init = raven_pcihost_class_init, }; -static void raven_register_devices(void) +static void raven_register_types(void) { type_register_static(&raven_pcihost_info); type_register_static(&raven_info); } -device_init(raven_register_devices) +type_init(raven_register_types) diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index 244c614..1ab2701 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -2330,7 +2330,7 @@ static TypeInfo pxa2xx_ssp_info = { .class_init = pxa2xx_ssp_class_init, }; -static void pxa2xx_register_devices(void) +static void pxa2xx_register_types(void) { type_register_static(&pxa2xx_i2c_slave_info); type_register_static(&pxa2xx_ssp_info); @@ -2338,4 +2338,4 @@ static void pxa2xx_register_devices(void) type_register_static(&pxa2xx_rtc_sysbus_info); } -device_init(pxa2xx_register_devices) +type_init(pxa2xx_register_types) diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c index 2d61565..8ced0dd 100644 --- a/hw/pxa2xx_dma.c +++ b/hw/pxa2xx_dma.c @@ -566,8 +566,9 @@ static TypeInfo pxa2xx_dma_info = { .class_init = pxa2xx_dma_class_init, }; -static void pxa2xx_dma_register(void) +static void pxa2xx_dma_register_types(void) { type_register_static(&pxa2xx_dma_info); } -device_init(pxa2xx_dma_register); + +type_init(pxa2xx_dma_register_types) diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c index 67fd17c..d5f5716 100644 --- a/hw/pxa2xx_gpio.c +++ b/hw/pxa2xx_gpio.c @@ -340,8 +340,9 @@ static TypeInfo pxa2xx_gpio_info = { .class_init = pxa2xx_gpio_class_init, }; -static void pxa2xx_gpio_register(void) +static void pxa2xx_gpio_register_types(void) { type_register_static(&pxa2xx_gpio_info); } -device_init(pxa2xx_gpio_register); + +type_init(pxa2xx_gpio_register_types) diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c index ca85743..6b2bdb0 100644 --- a/hw/pxa2xx_pic.c +++ b/hw/pxa2xx_pic.c @@ -313,8 +313,9 @@ static TypeInfo pxa2xx_pic_info = { .class_init = pxa2xx_pic_class_init, }; -static void pxa2xx_pic_register(void) +static void pxa2xx_pic_register_types(void) { type_register_static(&pxa2xx_pic_info); } -device_init(pxa2xx_pic_register); + +type_init(pxa2xx_pic_register_types) diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c index 9080075..77b033b 100644 --- a/hw/pxa2xx_timer.c +++ b/hw/pxa2xx_timer.c @@ -527,9 +527,10 @@ static TypeInfo pxa27x_timer_dev_info = { .class_init = pxa27x_timer_dev_class_init, }; -static void pxa2xx_timer_register(void) +static void pxa2xx_timer_register_types(void) { type_register_static(&pxa25x_timer_dev_info); type_register_static(&pxa27x_timer_dev_info); -}; -device_init(pxa2xx_timer_register); +} + +type_init(pxa2xx_timer_register_types) diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c index 5976dcd..0bb16c7 100644 --- a/hw/qdev-addr.c +++ b/hw/qdev-addr.c @@ -61,8 +61,6 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_taddr = { .name = "taddr", - .type = PROP_TYPE_TADDR, - .size = sizeof(target_phys_addr_t), .parse = parse_taddr, .print = print_taddr, .get = get_taddr, @@ -71,5 +69,8 @@ PropertyInfo qdev_prop_taddr = { void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert(!errp); + } diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 135c2bf..a310cc7 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -457,6 +457,16 @@ DeviceState *qdev_device_add(QemuOpts *opts) id = qemu_opts_id(opts); if (id) { qdev->id = id; + } + if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { + qdev_free(qdev); + return NULL; + } + if (qdev_init(qdev) < 0) { + qerror_report(QERR_DEVICE_INIT_FAILED, driver); + return NULL; + } + if (qdev->id) { object_property_add_child(qdev_get_peripheral(), qdev->id, OBJECT(qdev), NULL); } else { @@ -466,14 +476,6 @@ DeviceState *qdev_device_add(QemuOpts *opts) OBJECT(qdev), NULL); g_free(name); } - if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { - qdev_free(qdev); - return NULL; - } - if (qdev_init(qdev) < 0) { - qerror_report(QERR_DEVICE_INIT_FAILED, driver); - return NULL; - } qdev->opts = opts; return qdev; } @@ -485,22 +487,26 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent); static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, const char *prefix, int indent) { - char buf[64]; - if (!props) return; - while (props->name) { - /* - * TODO Properties without a print method are just for dirty - * hacks. qdev_prop_ptr is the only such PropertyInfo. It's - * marked for removal. The test props->info->print should be - * removed along with it. - */ - if (props->info->print) { - props->info->print(dev, props, buf, sizeof(buf)); - qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf); + for (; props->name; props++) { + Error *err = NULL; + char *value; + char *legacy_name = g_strdup_printf("legacy-%s", props->name); + if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { + value = object_property_get_str(OBJECT(dev), legacy_name, &err); + } else { + value = object_property_get_str(OBJECT(dev), props->name, &err); + } + g_free(legacy_name); + + if (err) { + error_free(err); + continue; } - props++; + qdev_printf("%s-prop: %s = %s\n", prefix, props->name, + value && *value ? value : "<null>"); + g_free(value); } } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index c4583a1..7b74dd5 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -12,7 +12,7 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) static uint32_t qdev_get_prop_mask(Property *prop) { - assert(prop->info->type == PROP_TYPE_BIT); + assert(prop->info == &qdev_prop_bit); return 0x1 << prop->bitnr; } @@ -26,17 +26,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val) *p &= ~mask; } -static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src) -{ - if (props->info->type == PROP_TYPE_BIT) { - bool *defval = src; - bit_prop_set(dev, props, *defval); - } else { - char *dst = qdev_get_prop_ptr(dev, props); - memcpy(dst, src, props->info->size); - } -} - /* Bit */ static int parse_bit(DeviceState *dev, Property *prop, const char *str) { @@ -90,8 +79,6 @@ static void set_bit(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_bit = { .name = "boolean", .legacy_name = "on/off", - .type = PROP_TYPE_BIT, - .size = sizeof(uint32_t), .parse = parse_bit, .print = print_bit, .get = get_bit, @@ -151,7 +138,7 @@ static void set_int8(Object *obj, Visitor *v, void *opaque, error_propagate(errp, local_err); return; } - if (value > prop->info->min && value <= prop->info->max) { + if (value >= prop->info->min && value <= prop->info->max) { *ptr = value; } else { error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, @@ -162,8 +149,6 @@ static void set_int8(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_uint8 = { .name = "uint8", - .type = PROP_TYPE_UINT8, - .size = sizeof(uint8_t), .parse = parse_uint8, .print = print_uint8, .get = get_int8, @@ -196,8 +181,6 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len) PropertyInfo qdev_prop_hex8 = { .name = "uint8", .legacy_name = "hex8", - .type = PROP_TYPE_UINT8, - .size = sizeof(uint8_t), .parse = parse_hex8, .print = print_hex8, .get = get_int8, @@ -259,7 +242,7 @@ static void set_int16(Object *obj, Visitor *v, void *opaque, error_propagate(errp, local_err); return; } - if (value > prop->info->min && value <= prop->info->max) { + if (value >= prop->info->min && value <= prop->info->max) { *ptr = value; } else { error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, @@ -270,8 +253,6 @@ static void set_int16(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_uint16 = { .name = "uint16", - .type = PROP_TYPE_UINT16, - .size = sizeof(uint16_t), .parse = parse_uint16, .print = print_uint16, .get = get_int16, @@ -333,7 +314,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque, error_propagate(errp, local_err); return; } - if (value > prop->info->min && value <= prop->info->max) { + if (value >= prop->info->min && value <= prop->info->max) { *ptr = value; } else { error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, @@ -344,8 +325,6 @@ static void set_int32(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_uint32 = { .name = "uint32", - .type = PROP_TYPE_UINT32, - .size = sizeof(uint32_t), .parse = parse_uint32, .print = print_uint32, .get = get_int32, @@ -375,8 +354,6 @@ static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len) PropertyInfo qdev_prop_int32 = { .name = "int32", - .type = PROP_TYPE_INT32, - .size = sizeof(int32_t), .parse = parse_int32, .print = print_int32, .get = get_int32, @@ -409,8 +386,6 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len) PropertyInfo qdev_prop_hex32 = { .name = "uint32", .legacy_name = "hex32", - .type = PROP_TYPE_UINT32, - .size = sizeof(uint32_t), .parse = parse_hex32, .print = print_hex32, .get = get_int32, @@ -468,8 +443,6 @@ static void set_int64(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_uint64 = { .name = "uint64", - .type = PROP_TYPE_UINT64, - .size = sizeof(uint64_t), .parse = parse_uint64, .print = print_uint64, .get = get_int64, @@ -500,8 +473,6 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len) PropertyInfo qdev_prop_hex64 = { .name = "uint64", .legacy_name = "hex64", - .type = PROP_TYPE_UINT64, - .size = sizeof(uint64_t), .parse = parse_hex64, .print = print_hex64, .get = get_int64, @@ -510,19 +481,10 @@ PropertyInfo qdev_prop_hex64 = { /* --- string --- */ -static int parse_string(DeviceState *dev, Property *prop, const char *str) -{ - char **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) - g_free(*ptr); - *ptr = g_strdup(str); - return 0; -} - -static void free_string(DeviceState *dev, Property *prop) +static void release_string(Object *obj, const char *name, void *opaque) { - g_free(*(char **)qdev_get_prop_ptr(dev, prop)); + Property *prop = opaque; + g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop)); } static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len) @@ -579,20 +541,16 @@ static void set_string(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_string = { .name = "string", - .type = PROP_TYPE_STRING, - .size = sizeof(char*), - .parse = parse_string, .print = print_string, - .free = free_string, + .release = release_string, .get = get_string, .set = set_string, }; /* --- drive --- */ -static int parse_drive(DeviceState *dev, Property *prop, const char *str) +static int parse_drive(DeviceState *dev, const char *str, void **ptr) { - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); BlockDriverState *bs; bs = bdrv_find(str); @@ -604,8 +562,10 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str) return 0; } -static void free_drive(DeviceState *dev, Property *prop) +static void release_drive(Object *obj, const char *name, void *opaque) { + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); if (*ptr) { @@ -614,35 +574,30 @@ static void free_drive(DeviceState *dev, Property *prop) } } -static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len) +static const char *print_drive(void *ptr) { - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); - return snprintf(dest, len, "%s", - *ptr ? bdrv_get_device_name(*ptr) : "<null>"); + return bdrv_get_device_name(ptr); } -static void get_generic(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) +static void get_pointer(Object *obj, Visitor *v, Property *prop, + const char *(*print)(void *ptr), + const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); - Property *prop = opaque; void **ptr = qdev_get_prop_ptr(dev, prop); - char buffer[1024]; - char *p = buffer; + char *p; - buffer[0] = 0; - if (*ptr) { - prop->info->print(dev, prop, buffer, sizeof(buffer)); - } + p = (char *) (*ptr ? print(*ptr) : ""); visit_type_str(v, &p, name, errp); } -static void set_generic(Object *obj, Visitor *v, void *opaque, +static void set_pointer(Object *obj, Visitor *v, Property *prop, + int (*parse)(DeviceState *dev, const char *str, void **ptr), const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); - Property *prop = opaque; Error *local_err = NULL; + void **ptr = qdev_get_prop_ptr(dev, prop); char *str; int ret; @@ -658,44 +613,53 @@ static void set_generic(Object *obj, Visitor *v, void *opaque, } if (!*str) { g_free(str); - error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); + *ptr = NULL; return; } - ret = prop->info->parse(dev, prop, str); + ret = parse(dev, str, ptr); error_set_from_qdev_prop_error(errp, ret, dev, prop, str); g_free(str); } +static void get_drive(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_drive, name, errp); +} + +static void set_drive(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_drive, name, errp); +} + PropertyInfo qdev_prop_drive = { .name = "drive", - .type = PROP_TYPE_DRIVE, - .size = sizeof(BlockDriverState *), - .parse = parse_drive, - .print = print_drive, - .get = get_generic, - .set = set_generic, - .free = free_drive, + .get = get_drive, + .set = set_drive, + .release = release_drive, }; /* --- character device --- */ -static int parse_chr(DeviceState *dev, Property *prop, const char *str) +static int parse_chr(DeviceState *dev, const char *str, void **ptr) { - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - - *ptr = qemu_chr_find(str); - if (*ptr == NULL) { + CharDriverState *chr = qemu_chr_find(str); + if (chr == NULL) { return -ENOENT; } - if ((*ptr)->avail_connections < 1) { + if (chr->avail_connections < 1) { return -EEXIST; } - --(*ptr)->avail_connections; + *ptr = chr; + --chr->avail_connections; return 0; } -static void free_chr(DeviceState *dev, Property *prop) +static void release_chr(Object *obj, const char *name, void *opaque) { + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); if (*ptr) { @@ -704,62 +668,71 @@ static void free_chr(DeviceState *dev, Property *prop) } -static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len) +static const char *print_chr(void *ptr) { - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); + CharDriverState *chr = ptr; - if (*ptr && (*ptr)->label) { - return snprintf(dest, len, "%s", (*ptr)->label); - } else { - return snprintf(dest, len, "<null>"); - } + return chr->label ? chr->label : ""; +} + +static void get_chr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_chr, name, errp); +} + +static void set_chr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_chr, name, errp); } PropertyInfo qdev_prop_chr = { .name = "chr", - .type = PROP_TYPE_CHR, - .size = sizeof(CharDriverState*), - .parse = parse_chr, - .print = print_chr, - .get = get_generic, - .set = set_generic, - .free = free_chr, + .get = get_chr, + .set = set_chr, + .release = release_chr, }; /* --- netdev device --- */ -static int parse_netdev(DeviceState *dev, Property *prop, const char *str) +static int parse_netdev(DeviceState *dev, const char *str, void **ptr) { - VLANClientState **ptr = qdev_get_prop_ptr(dev, prop); + VLANClientState *netdev = qemu_find_netdev(str); - *ptr = qemu_find_netdev(str); - if (*ptr == NULL) + if (netdev == NULL) { return -ENOENT; - if ((*ptr)->peer) { + } + if (netdev->peer) { return -EEXIST; } + *ptr = netdev; return 0; } -static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len) +static const char *print_netdev(void *ptr) { - VLANClientState **ptr = qdev_get_prop_ptr(dev, prop); + VLANClientState *netdev = ptr; - if (*ptr && (*ptr)->name) { - return snprintf(dest, len, "%s", (*ptr)->name); - } else { - return snprintf(dest, len, "<null>"); - } + return netdev->name ? netdev->name : ""; +} + +static void get_netdev(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_netdev, name, errp); +} + +static void set_netdev(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_netdev, name, errp); } PropertyInfo qdev_prop_netdev = { .name = "netdev", - .type = PROP_TYPE_NETDEV, - .size = sizeof(VLANClientState*), - .parse = parse_netdev, - .print = print_netdev, - .get = get_generic, - .set = set_generic, + .get = get_netdev, + .set = set_netdev, }; /* --- vlan --- */ @@ -835,8 +808,6 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, PropertyInfo qdev_prop_vlan = { .name = "vlan", - .type = PROP_TYPE_VLAN, - .size = sizeof(VLANClientState*), .parse = parse_vlan, .print = print_vlan, .get = get_vlan, @@ -848,8 +819,6 @@ PropertyInfo qdev_prop_vlan = { /* Not a proper property, just for dirty hacks. TODO Remove it! */ PropertyInfo qdev_prop_ptr = { .name = "ptr", - .type = PROP_TYPE_PTR, - .size = sizeof(void*), }; /* --- mac address --- */ @@ -859,95 +828,114 @@ PropertyInfo qdev_prop_ptr = { * 01:02:03:04:05:06 * 01-02-03-04-05-06 */ -static int parse_mac(DeviceState *dev, Property *prop, const char *str) +static void get_mac(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + MACAddr *mac = qdev_get_prop_ptr(dev, prop); + char buffer[2 * 6 + 5 + 1]; + char *p = buffer; + + snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x", + mac->a[0], mac->a[1], mac->a[2], + mac->a[3], mac->a[4], mac->a[5]); + + visit_type_str(v, &p, name, errp); +} + +static void set_mac(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; MACAddr *mac = qdev_get_prop_ptr(dev, prop); + Error *local_err = NULL; int i, pos; - char *p; + char *str, *p; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_str(v, &str, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } for (i = 0, pos = 0; i < 6; i++, pos += 3) { if (!qemu_isxdigit(str[pos])) - return -EINVAL; + goto inval; if (!qemu_isxdigit(str[pos+1])) - return -EINVAL; + goto inval; if (i == 5) { if (str[pos+2] != '\0') - return -EINVAL; + goto inval; } else { if (str[pos+2] != ':' && str[pos+2] != '-') - return -EINVAL; + goto inval; } mac->a[i] = strtol(str+pos, &p, 16); } - return 0; -} + return; -static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len) -{ - MACAddr *mac = qdev_get_prop_ptr(dev, prop); - - return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x", - mac->a[0], mac->a[1], mac->a[2], - mac->a[3], mac->a[4], mac->a[5]); +inval: + error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); } PropertyInfo qdev_prop_macaddr = { .name = "macaddr", - .type = PROP_TYPE_MACADDR, - .size = sizeof(MACAddr), - .parse = parse_mac, - .print = print_mac, - .get = get_generic, - .set = set_generic, + .get = get_mac, + .set = set_mac, }; /* --- lost tick policy --- */ -static const struct { - const char *name; - LostTickPolicy code; -} lost_tick_policy_table[] = { - { .name = "discard", .code = LOST_TICK_DISCARD }, - { .name = "delay", .code = LOST_TICK_DELAY }, - { .name = "merge", .code = LOST_TICK_MERGE }, - { .name = "slew", .code = LOST_TICK_SLEW }, +static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = { + [LOST_TICK_DISCARD] = "discard", + [LOST_TICK_DELAY] = "delay", + [LOST_TICK_MERGE] = "merge", + [LOST_TICK_SLEW] = "slew", + [LOST_TICK_MAX] = NULL, }; -static int parse_lost_tick_policy(DeviceState *dev, Property *prop, - const char *str) +QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); + +static void get_enum(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) { - LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop); - int i; + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int *ptr = qdev_get_prop_ptr(dev, prop); - for (i = 0; i < ARRAY_SIZE(lost_tick_policy_table); i++) { - if (!strcasecmp(str, lost_tick_policy_table[i].name)) { - *ptr = lost_tick_policy_table[i].code; - break; - } - } - if (i == ARRAY_SIZE(lost_tick_policy_table)) { - return -EINVAL; - } - return 0; + visit_type_enum(v, ptr, prop->info->enum_table, + prop->info->name, prop->name, errp); } -static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest, - size_t len) +static void set_enum(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) { - LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop); + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int *ptr = qdev_get_prop_ptr(dev, prop); + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } - return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name); + visit_type_enum(v, ptr, prop->info->enum_table, + prop->info->name, prop->name, errp); } PropertyInfo qdev_prop_losttickpolicy = { - .name = "lost_tick_policy", - .type = PROP_TYPE_LOSTTICKPOLICY, - .size = sizeof(LostTickPolicy), - .parse = parse_lost_tick_policy, - .print = print_lost_tick_policy, - .get = get_generic, - .set = set_generic, + .name = "LostTickPolicy", + .enum_table = lost_tick_policy_table, + .get = get_enum, + .set = set_enum, }; /* --- pci address --- */ @@ -987,30 +975,18 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t } } -static void get_pci_devfn(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - uint32_t *ptr = qdev_get_prop_ptr(dev, prop); - char buffer[32]; - char *p = buffer; - - buffer[0] = 0; - if (*ptr != -1) { - snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7); - } - visit_type_str(v, &p, name, errp); -} - PropertyInfo qdev_prop_pci_devfn = { - .name = "pci-devfn", - .type = PROP_TYPE_UINT32, - .size = sizeof(uint32_t), + .name = "int32", + .legacy_name = "pci-devfn", .parse = parse_pci_devfn, .print = print_pci_devfn, - .get = get_pci_devfn, - .set = set_generic, + .get = get_int32, + .set = set_int32, + /* FIXME: this should be -1...255, but the address is stored + * into an uint32_t rather than int32_t. + */ + .min = 0, + .max = 0xFFFFFFFFULL, }; /* --- public helpers --- */ @@ -1073,24 +1049,18 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) { - Property *prop; - int ret; + char *legacy_name; + Error *err = NULL; - prop = qdev_prop_find(dev, name); - /* - * TODO Properties without a parse method are just for dirty - * hacks. qdev_prop_ptr is the only such PropertyInfo. It's - * marked for removal. The test !prop->info->parse should be - * removed along with it. - */ - if (!prop || !prop->info->parse) { - qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name); - return -1; + legacy_name = g_strdup_printf("legacy-%s", name); + if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { + object_property_set_str(OBJECT(dev), value, legacy_name, &err); + } else { + object_property_set_str(OBJECT(dev), value, name, &err); } - ret = prop->info->parse(dev, prop, value); - if (ret < 0) { - Error *err; - error_set_from_qdev_prop_error(&err, ret, dev, prop, value); + g_free(legacy_name); + + if (err) { qerror_report_err(err); error_free(err); return -1; @@ -1098,72 +1068,66 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) return 0; } -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) -{ - Property *prop; - - prop = qdev_prop_find(dev, name); - if (!prop) { - fprintf(stderr, "%s: property \"%s.%s\" not found\n", - __FUNCTION__, object_get_typename(OBJECT(dev)), name); - abort(); - } - if (prop->info->type != type) { - fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n", - __FUNCTION__, object_get_typename(OBJECT(dev)), name); - abort(); - } - qdev_prop_cpy(dev, prop, src); -} - void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_BIT); + Error *errp = NULL; + object_property_set_bool(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_INT32); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } void qdev_prop_set_string(DeviceState *dev, const char *name, char *value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_STRING); + Error *errp = NULL; + object_property_set_str(OBJECT(dev), value, name, &errp); + assert_no_error(errp); } int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) { - int res; - - res = bdrv_attach_dev(value, dev); - if (res < 0) { - error_report("Can't attach drive %s to %s.%s: %s", - bdrv_get_device_name(value), - dev->id ? dev->id : object_get_typename(OBJECT(dev)), - name, strerror(-res)); + Error *errp = NULL; + const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; + object_property_set_str(OBJECT(dev), bdrv_name, + name, &errp); + if (errp) { + qerror_report_err(errp); + error_free(errp); return -1; } - qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE); return 0; } @@ -1175,44 +1139,81 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverS } void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_CHR); + Error *errp = NULL; + assert(!value || value->label); + object_property_set_str(OBJECT(dev), + value ? value->label : "", name, &errp); + assert_no_error(errp); } void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV); + Error *errp = NULL; + assert(!value || value->name); + object_property_set_str(OBJECT(dev), + value ? value->name : "", name, &errp); + assert_no_error(errp); } void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN); + Error *errp = NULL; + object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp); + assert_no_error(errp); } void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) { - qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR); + Error *errp = NULL; + char str[2 * 6 + 5 + 1]; + snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", + value[0], value[1], value[2], value[3], value[4], value[5]); + + object_property_set_str(OBJECT(dev), str, name, &errp); + assert_no_error(errp); } -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name, - LostTickPolicy *value) +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) { - qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY); + Property *prop; + Error *errp = NULL; + + prop = qdev_prop_find(dev, name); + object_property_set_str(OBJECT(dev), prop->info->enum_table[value], + name, &errp); + assert_no_error(errp); } void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) { - qdev_prop_set(dev, name, &value, PROP_TYPE_PTR); + Property *prop; + void **ptr; + + prop = qdev_prop_find(dev, name); + assert(prop && prop->info == &qdev_prop_ptr); + ptr = qdev_get_prop_ptr(dev, prop); + *ptr = value; } void qdev_prop_set_defaults(DeviceState *dev, Property *props) { + Object *obj = OBJECT(dev); if (!props) return; - while (props->name) { - if (props->defval) { - qdev_prop_cpy(dev, props, props->defval); + for (; props->name; props++) { + Error *errp = NULL; + if (props->qtype == QTYPE_NONE) { + continue; } - props++; + if (props->qtype == QTYPE_QBOOL) { + object_property_set_bool(obj, props->defval, props->name, &errp); + } else if (props->info->enum_table) { + object_property_set_str(obj, props->info->enum_table[props->defval], + props->name, &errp); + } else if (props->qtype == QTYPE_QINT) { + object_property_set_int(obj, props->defval, props->name, &errp); + } + assert_no_error(errp); } } @@ -86,11 +86,11 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus) dev->parent_bus = bus; QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); - qdev_prop_set_defaults(dev, dev->parent_bus->info->props); for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) { qdev_property_add_legacy(dev, prop, NULL); qdev_property_add_static(dev, prop, NULL); } + qdev_prop_set_defaults(dev, dev->parent_bus->info->props); } /* Create a new device. This only initializes the device state structure @@ -550,21 +550,24 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque, * Do not use this is new code! Properties added through this interface will * be given names and types in the "legacy" namespace. * - * Legacy properties are always processed as strings. The format of the string - * depends on the property type. + * Legacy properties are string versions of other OOM properties. The format + * of the string depends on the property type. */ void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp) { gchar *name, *type; + if (!prop->info->print && !prop->info->parse) { + return; + } name = g_strdup_printf("legacy-%s", prop->name); type = g_strdup_printf("legacy<%s>", prop->info->legacy_name ?: prop->info->name); object_property_add(OBJECT(dev), name, type, - prop->info->print ? qdev_get_legacy_property : NULL, - prop->info->parse ? qdev_set_legacy_property : NULL, + prop->info->print ? qdev_get_legacy_property : prop->info->get, + prop->info->parse ? qdev_set_legacy_property : prop->info->set, NULL, prop, errp); @@ -581,9 +584,18 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) { + /* + * TODO qdev_prop_ptr does not have getters or setters. It must + * go now that it can be replaced with links. The test should be + * removed along with it: all static properties are read/write. + */ + if (!prop->info->get && !prop->info->set) { + return; + } + object_property_add(OBJECT(dev), prop->name, prop->info->name, prop->info->get, prop->info->set, - NULL, + prop->info->release, prop, errp); } @@ -600,13 +612,13 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->state = DEV_STATE_CREATED; - qdev_prop_set_defaults(dev, qdev_get_props(dev)); for (prop = qdev_get_props(dev); prop && prop->name; prop++) { qdev_property_add_legacy(dev, prop, NULL); qdev_property_add_static(dev, prop, NULL); } object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL); + qdev_prop_set_defaults(dev, qdev_get_props(dev)); } /* Unlink device from bus and free the structure. */ @@ -614,7 +626,6 @@ static void device_finalize(Object *obj) { DeviceState *dev = DEVICE(obj); BusState *bus; - Property *prop; DeviceClass *dc = DEVICE_GET_CLASS(dev); if (dev->state == DEV_STATE_INITIALIZED) { @@ -633,11 +644,6 @@ static void device_finalize(Object *obj) } } QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); - for (prop = qdev_get_props(dev); prop && prop->name; prop++) { - if (prop->info->free) { - prop->info->free(dev, prop); - } - } } void device_reset(DeviceState *dev) @@ -659,9 +665,9 @@ static TypeInfo device_type_info = { .class_size = sizeof(DeviceClass), }; -static void init_qdev(void) +static void qdev_register_types(void) { type_register_static(&device_type_info); } -device_init(init_qdev); +type_init(qdev_register_types) @@ -112,41 +112,22 @@ struct Property { const char *name; PropertyInfo *info; int offset; - int bitnr; - void *defval; -}; - -enum PropertyType { - PROP_TYPE_UNSPEC = 0, - PROP_TYPE_UINT8, - PROP_TYPE_UINT16, - PROP_TYPE_UINT32, - PROP_TYPE_INT32, - PROP_TYPE_UINT64, - PROP_TYPE_TADDR, - PROP_TYPE_MACADDR, - PROP_TYPE_LOSTTICKPOLICY, - PROP_TYPE_DRIVE, - PROP_TYPE_CHR, - PROP_TYPE_STRING, - PROP_TYPE_NETDEV, - PROP_TYPE_VLAN, - PROP_TYPE_PTR, - PROP_TYPE_BIT, + uint8_t bitnr; + uint8_t qtype; + int64_t defval; }; struct PropertyInfo { const char *name; const char *legacy_name; - size_t size; - enum PropertyType type; + const char **enum_table; int64_t min; int64_t max; int (*parse)(DeviceState *dev, Property *prop, const char *str); int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); - void (*free)(DeviceState *dev, Property *prop); ObjectPropertyAccessor *get; ObjectPropertyAccessor *set; + ObjectPropertyRelease *release; }; typedef struct GlobalProperty { @@ -254,7 +235,8 @@ extern PropertyInfo qdev_prop_pci_devfn; .info = &(_prop), \ .offset = offsetof(_state, _field) \ + type_check(_type,typeof_field(_state, _field)), \ - .defval = (_type[]) { _defval }, \ + .qtype = QTYPE_QINT, \ + .defval = (_type)_defval, \ } #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \ .name = (_name), \ @@ -262,7 +244,8 @@ extern PropertyInfo qdev_prop_pci_devfn; .bitnr = (_bit), \ .offset = offsetof(_state, _field) \ + type_check(uint32_t,typeof_field(_state, _field)), \ - .defval = (bool[]) { (_defval) }, \ + .qtype = QTYPE_QBOOL, \ + .defval = (bool)_defval, \ } #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ @@ -309,7 +292,6 @@ extern PropertyInfo qdev_prop_pci_devfn; void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); int qdev_prop_exists(DeviceState *dev, const char *name); int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type); void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value); void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value); void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value); @@ -323,8 +305,7 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value); int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT; void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value); void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value); -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name, - LostTickPolicy *value); +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); /* FIXME: Remove opaque pointer properties. */ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); void qdev_prop_set_defaults(DeviceState *dev, Property *props); @@ -1870,10 +1870,10 @@ static TypeInfo qxl_secondary_info = { .class_init = qxl_secondary_class_init, }; -static void qxl_register(void) +static void qxl_register_types(void) { type_register_static(&qxl_primary_info); type_register_static(&qxl_secondary_info); } -device_init(qxl_register); +type_init(qxl_register_types) diff --git a/hw/realview.c b/hw/realview.c index 821e627..bcf982f 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -96,7 +96,7 @@ static TypeInfo realview_i2c_info = { .class_init = realview_i2c_class_init, }; -static void realview_register_devices(void) +static void realview_register_types(void) { type_register_static(&realview_i2c_info); } @@ -217,8 +217,8 @@ static void realview_init(ram_addr_t ram_size, sys_id = is_pb ? 0x01780500 : 0xc1400400; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); - qdev_init_nofail(sysctl); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); + qdev_init_nofail(sysctl); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); if (is_mpcore) { @@ -491,4 +491,4 @@ static void realview_machine_init(void) } machine_init(realview_machine_init); -device_init(realview_register_devices) +type_init(realview_register_types) diff --git a/hw/realview_gic.c b/hw/realview_gic.c index 4121502..071ef13 100644 --- a/hw/realview_gic.c +++ b/hw/realview_gic.c @@ -60,9 +60,9 @@ static TypeInfo realview_gic_info = { .class_init = realview_gic_class_init, }; -static void realview_gic_register_devices(void) +static void realview_gic_register_types(void) { type_register_static(&realview_gic_info); } -device_init(realview_gic_register_devices) +type_init(realview_gic_register_types) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 1668390..05b8e1e 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3523,9 +3523,9 @@ static TypeInfo rtl8139_info = { .class_init = rtl8139_class_init, }; -static void rtl8139_register_devices(void) +static void rtl8139_register_types(void) { type_register_static(&rtl8139_info); } -device_init(rtl8139_register_devices) +type_init(rtl8139_register_types) diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index 49140f8..9d48056 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -433,15 +433,6 @@ static TypeInfo virtio_s390_device_info = { .abstract = true, }; -static void s390_virtio_register(void) -{ - type_register_static(&virtio_s390_device_info); - type_register_static(&s390_virtio_serial); - type_register_static(&s390_virtio_blk); - type_register_static(&s390_virtio_net); -} -device_init(s390_virtio_register); - /***************** S390 Virtio Bus Bridge Device *******************/ /* Only required to have the virtio bus as child in the system bus */ @@ -468,9 +459,13 @@ static TypeInfo s390_virtio_bridge_info = { .class_init = s390_virtio_bridge_class_init, }; -static void s390_virtio_register_devices(void) +static void s390_virtio_register_types(void) { + type_register_static(&virtio_s390_device_info); + type_register_static(&s390_virtio_serial); + type_register_static(&s390_virtio_blk); + type_register_static(&s390_virtio_net); type_register_static(&s390_virtio_bridge_info); } -device_init(s390_virtio_register_devices) +type_init(s390_virtio_register_types) @@ -1417,8 +1417,9 @@ static TypeInfo sb16_info = { .class_init = sb16_class_initfn, }; -static void sb16_register (void) +static void sb16_register_types (void) { type_register_static (&sb16_info); } -device_init (sb16_register) + +type_init (sb16_register_types) @@ -148,9 +148,9 @@ static TypeInfo sbi_info = { .class_init = sbi_class_init, }; -static void sbi_register_devices(void) +static void sbi_register_types(void) { type_register_static(&sbi_info); } -device_init(sbi_register_devices) +type_init(sbi_register_types) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 0ee50a8..b3e97ce 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -1431,9 +1431,9 @@ static TypeInfo scsi_device_type_info = { .class_init = scsi_device_class_init, }; -static void scsi_register_devices(void) +static void scsi_register_types(void) { type_register_static(&scsi_device_type_info); } -device_init(scsi_register_devices); +type_init(scsi_register_types) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 399e51e..c12e3a6 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1823,7 +1823,7 @@ static TypeInfo scsi_disk_info = { .class_init = scsi_disk_class_initfn, }; -static void scsi_disk_register_devices(void) +static void scsi_disk_register_types(void) { type_register_static(&scsi_hd_info); type_register_static(&scsi_cd_info); @@ -1832,4 +1832,5 @@ static void scsi_disk_register_devices(void) #endif type_register_static(&scsi_disk_info); } -device_init(scsi_disk_register_devices) + +type_init(scsi_disk_register_types) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 4859212..86014aa 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -483,10 +483,11 @@ static TypeInfo scsi_generic_info = { .class_init = scsi_generic_class_initfn, }; -static void scsi_generic_register_devices(void) +static void scsi_generic_register_types(void) { type_register_static(&scsi_generic_info); } -device_init(scsi_generic_register_devices) + +type_init(scsi_generic_register_types) #endif /* __linux__ */ diff --git a/hw/serial.c b/hw/serial.c index 82917e2..144d1b3 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -903,9 +903,9 @@ static TypeInfo serial_isa_info = { .class_init = serial_isa_class_initfn, }; -static void serial_register_devices(void) +static void serial_register_types(void) { type_register_static(&serial_isa_info); } -device_init(serial_register_devices) +type_init(serial_register_types) @@ -55,9 +55,9 @@ static TypeInfo sga_info = { .class_init = sga_class_initfn, }; -static void sga_register(void) +static void sga_register_types(void) { type_register_static(&sga_info); } -device_init(sga_register); +type_init(sga_register_types) diff --git a/hw/sh_pci.c b/hw/sh_pci.c index 4234d93..0cfac46 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -177,10 +177,10 @@ static TypeInfo sh_pci_device_info = { .class_init = sh_pci_device_class_init, }; -static void sh_pci_register_devices(void) +static void sh_pci_register_types(void) { type_register_static(&sh_pci_device_info); type_register_static(&sh_pci_host_info); } -device_init(sh_pci_register_devices) +type_init(sh_pci_register_types) diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c index e3701c7..7fdc3be 100644 --- a/hw/slavio_intctl.c +++ b/hw/slavio_intctl.c @@ -463,9 +463,9 @@ static TypeInfo slavio_intctl_info = { .class_init = slavio_intctl_class_init, }; -static void slavio_intctl_register_devices(void) +static void slavio_intctl_register_types(void) { type_register_static(&slavio_intctl_info); } -device_init(slavio_intctl_register_devices) +type_init(slavio_intctl_register_types) diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c index 5a02518..944835e 100644 --- a/hw/slavio_misc.c +++ b/hw/slavio_misc.c @@ -499,10 +499,10 @@ static TypeInfo apc_info = { .class_init = apc_class_init, }; -static void slavio_misc_register_devices(void) +static void slavio_misc_register_types(void) { type_register_static(&slavio_misc_info); type_register_static(&apc_info); } -device_init(slavio_misc_register_devices) +type_init(slavio_misc_register_types) diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c index 3878f6f..97edebb 100644 --- a/hw/slavio_timer.c +++ b/hw/slavio_timer.c @@ -427,9 +427,9 @@ static TypeInfo slavio_timer_info = { .class_init = slavio_timer_class_init, }; -static void slavio_timer_register_devices(void) +static void slavio_timer_register_types(void) { type_register_static(&slavio_timer_info); } -device_init(slavio_timer_register_devices) +type_init(slavio_timer_register_types) @@ -1327,8 +1327,8 @@ static void sm501_draw_crt(SM501State * s) ram_addr_t page1 = offset + width * src_bpp - 1; /* check dirty flags for each line */ - update = memory_region_get_dirty(&s->local_mem_region, page0, page1, - DIRTY_MEMORY_VGA); + update = memory_region_get_dirty(&s->local_mem_region, page0, + page1 - page0, DIRTY_MEMORY_VGA); /* draw line and change status */ if (update) { @@ -327,9 +327,9 @@ static TypeInfo smbus_device_type_info = { .class_init = smbus_device_class_init, }; -static void smbus_device_register_devices(void) +static void smbus_device_register_types(void) { type_register_static(&smbus_device_type_info); } -device_init(smbus_device_register_devices); +type_init(smbus_device_register_types) diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c index 9d96cbe..11adab0 100644 --- a/hw/smbus_eeprom.c +++ b/hw/smbus_eeprom.c @@ -130,12 +130,12 @@ static TypeInfo smbus_eeprom_info = { .class_init = smbus_eeprom_class_initfn, }; -static void smbus_eeprom_register_devices(void) +static void smbus_eeprom_register_types(void) { type_register_static(&smbus_eeprom_info); } -device_init(smbus_eeprom_register_devices) +type_init(smbus_eeprom_register_types) void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom, const uint8_t *eeprom_spd, int eeprom_spd_size) diff --git a/hw/smc91c111.c b/hw/smc91c111.c index 1bf2901..1a5213f 100644 --- a/hw/smc91c111.c +++ b/hw/smc91c111.c @@ -781,7 +781,7 @@ static TypeInfo smc91c111_info = { .class_init = smc91c111_class_init, }; -static void smc91c111_register_devices(void) +static void smc91c111_register_types(void) { type_register_static(&smc91c111_info); } @@ -802,4 +802,4 @@ void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq) sysbus_connect_irq(s, 0, irq); } -device_init(smc91c111_register_devices) +type_init(smc91c111_register_types) diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c index 84281be..6ac7384 100644 --- a/hw/spapr_hcall.c +++ b/hw/spapr_hcall.c @@ -672,7 +672,7 @@ target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, return H_FUNCTION; } -static void hypercall_init(void) +static void hypercall_register_types(void) { /* hcall-pft */ spapr_register_hypercall(H_ENTER, h_enter); @@ -704,4 +704,5 @@ static void hypercall_init(void) /* qemu/KVM-PPC specific hcalls */ spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas); } -device_init(hypercall_init); + +type_init(hypercall_register_types) diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c index 79b3941..77d4047 100644 --- a/hw/spapr_llan.c +++ b/hw/spapr_llan.c @@ -501,7 +501,7 @@ static TypeInfo spapr_vlan_info = { .class_init = spapr_vlan_class_init, }; -static void spapr_vlan_register(void) +static void spapr_vlan_register_types(void) { spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan); spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan); @@ -511,4 +511,5 @@ static void spapr_vlan_register(void) spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl); type_register_static(&spapr_vlan_info); } -device_init(spapr_vlan_register); + +type_init(spapr_vlan_register_types) diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index ed2e4b3..cfdd9dd 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -242,13 +242,13 @@ static TypeInfo spapr_phb_info = { .class_init = spapr_phb_class_init, }; -static void spapr_register_devices(void) +static void spapr_register_types(void) { type_register_static(&spapr_phb_info); type_register_static(&spapr_main_pci_host_info); } -device_init(spapr_register_devices) +type_init(spapr_register_types) static uint64_t spapr_io_read(void *opaque, target_phys_addr_t addr, unsigned size) diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c index d1ac74c..c0723b3 100644 --- a/hw/spapr_rtas.c +++ b/hw/spapr_rtas.c @@ -288,7 +288,7 @@ int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr, return 0; } -static void register_core_rtas(void) +static void core_rtas_register_types(void) { spapr_rtas_register("display-character", rtas_display_character); spapr_rtas_register("get-time-of-day", rtas_get_time_of_day); @@ -298,4 +298,5 @@ static void register_core_rtas(void) rtas_query_cpu_stopped_state); spapr_rtas_register("start-cpu", rtas_start_cpu); } -device_init(register_core_rtas); + +type_init(core_rtas_register_types) diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 64f0009..ea317ef 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -778,13 +778,13 @@ static TypeInfo spapr_vio_type_info = { .class_init = vio_spapr_device_class_init, }; -static void spapr_vio_register_devices(void) +static void spapr_vio_register_types(void) { type_register_static(&spapr_vio_bridge_info); type_register_static(&spapr_vio_type_info); } -device_init(spapr_vio_register_devices) +type_init(spapr_vio_register_types) #ifdef CONFIG_FDT static int compare_reg(const void *p1, const void *p2) diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c index 9cfce19..ffce261 100644 --- a/hw/spapr_vscsi.c +++ b/hw/spapr_vscsi.c @@ -973,8 +973,9 @@ static TypeInfo spapr_vscsi_info = { .class_init = spapr_vscsi_class_init, }; -static void spapr_vscsi_register(void) +static void spapr_vscsi_register_types(void) { type_register_static(&spapr_vscsi_info); } -device_init(spapr_vscsi_register); + +type_init(spapr_vscsi_register_types) diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c index a954e7d..3efe242 100644 --- a/hw/spapr_vty.c +++ b/hw/spapr_vty.c @@ -212,10 +212,11 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg) return sdev; } -static void spapr_vty_register(void) +static void spapr_vty_register_types(void) { spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char); spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char); type_register_static(&spapr_vty_info); } -device_init(spapr_vty_register); + +type_init(spapr_vty_register_types) diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c index f07cc6f..1dbf69e 100644 --- a/hw/sparc32_dma.c +++ b/hw/sparc32_dma.c @@ -307,9 +307,9 @@ static TypeInfo sparc32_dma_info = { .class_init = sparc32_dma_class_init, }; -static void sparc32_dma_register_devices(void) +static void sparc32_dma_register_types(void) { type_register_static(&sparc32_dma_info); } -device_init(sparc32_dma_register_devices) +type_init(sparc32_dma_register_types) @@ -1138,7 +1138,7 @@ static TypeInfo spitz_lcdtg_info = { .class_init = spitz_lcdtg_class_init, }; -static void spitz_register_devices(void) +static void spitz_register_types(void) { type_register_static(&corgi_ssp_info); type_register_static(&spitz_lcdtg_info); @@ -1146,4 +1146,4 @@ static void spitz_register_devices(void) type_register_static(&sl_nand_info); } -device_init(spitz_register_devices) +type_init(spitz_register_types) diff --git a/hw/ssd0303.c b/hw/ssd0303.c index 685602a..4e1ee6e 100644 --- a/hw/ssd0303.c +++ b/hw/ssd0303.c @@ -313,9 +313,9 @@ static TypeInfo ssd0303_info = { .class_init = ssd0303_class_init, }; -static void ssd0303_register_devices(void) +static void ssd0303_register_types(void) { type_register_static(&ssd0303_info); } -device_init(ssd0303_register_devices) +type_init(ssd0303_register_types) diff --git a/hw/ssd0323.c b/hw/ssd0323.c index 3c43738..b0b2e94 100644 --- a/hw/ssd0323.c +++ b/hw/ssd0323.c @@ -355,9 +355,9 @@ static TypeInfo ssd0323_info = { .class_init = ssd0323_class_init, }; -static void ssd03232_register_devices(void) +static void ssd03232_register_types(void) { type_register_static(&ssd0323_info); } -device_init(ssd03232_register_devices) +type_init(ssd03232_register_types) diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c index f2e6cec..b519bdb 100644 --- a/hw/ssi-sd.c +++ b/hw/ssi-sd.c @@ -259,9 +259,9 @@ static TypeInfo ssi_sd_info = { .class_init = ssi_sd_class_init, }; -static void ssi_sd_register_devices(void) +static void ssi_sd_register_types(void) { type_register_static(&ssi_sd_info); } -device_init(ssi_sd_register_devices) +type_init(ssi_sd_register_types) @@ -80,9 +80,9 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val) return ssc->transfer(slave, val); } -static void register_ssi_slave(void) +static void ssi_slave_register_types(void) { type_register_static(&ssi_slave_info); } -device_init(register_ssi_slave); +type_init(ssi_slave_register_types) diff --git a/hw/stellaris.c b/hw/stellaris.c index 31a65cfb..562fbbf 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -1451,7 +1451,7 @@ static TypeInfo stellaris_adc_info = { .class_init = stellaris_adc_class_init, }; -static void stellaris_register_devices(void) +static void stellaris_register_types(void) { type_register_static(&stellaris_i2c_info); type_register_static(&stellaris_gptm_info); @@ -1459,4 +1459,4 @@ static void stellaris_register_devices(void) type_register_static(&stellaris_ssi_bus_info); } -device_init(stellaris_register_devices) +type_init(stellaris_register_types) diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c index 9b1be8d..fbe99cb 100644 --- a/hw/stellaris_enet.c +++ b/hw/stellaris_enet.c @@ -441,9 +441,9 @@ static TypeInfo stellaris_enet_info = { .class_init = stellaris_enet_class_init, }; -static void stellaris_enet_register_devices(void) +static void stellaris_enet_register_types(void) { type_register_static(&stellaris_enet_info); } -device_init(stellaris_enet_register_devices) +type_init(stellaris_enet_register_types) diff --git a/hw/strongarm.c b/hw/strongarm.c index 8d2e7eb..4d5b60f 100644 --- a/hw/strongarm.c +++ b/hw/strongarm.c @@ -1609,7 +1609,7 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem, return s; } -static void strongarm_register_devices(void) +static void strongarm_register_types(void) { type_register_static(&strongarm_pic_info); type_register_static(&strongarm_rtc_sysbus_info); @@ -1618,4 +1618,5 @@ static void strongarm_register_devices(void) type_register_static(&strongarm_uart_info); type_register_static(&strongarm_ssp_info); } -device_init(strongarm_register_devices) + +type_init(strongarm_register_types) diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c index 081d6cc..8dfa5ec 100644 --- a/hw/sun4c_intctl.c +++ b/hw/sun4c_intctl.c @@ -223,9 +223,9 @@ static TypeInfo sun4c_intctl_info = { .class_init = sun4c_intctl_class_init, }; -static void sun4c_intctl_register_devices(void) +static void sun4c_intctl_register_types(void) { type_register_static(&sun4c_intctl_info); } -device_init(sun4c_intctl_register_devices) +type_init(sun4c_intctl_register_types) @@ -623,13 +623,6 @@ static TypeInfo idreg_info = { .class_init = idreg_class_init, }; -static void idreg_register_devices(void) -{ - type_register_static(&idreg_info); -} - -device_init(idreg_register_devices); - typedef struct AFXState { SysBusDevice busdev; MemoryRegion mem; @@ -672,13 +665,6 @@ static TypeInfo afx_info = { .class_init = afx_class_init, }; -static void afx_register_devices(void) -{ - type_register_static(&afx_info); -} - -device_init(afx_register_devices); - typedef struct PROMState { SysBusDevice busdev; MemoryRegion prom; @@ -756,13 +742,6 @@ static TypeInfo prom_info = { .class_init = prom_class_init, }; -static void prom_register_devices(void) -{ - type_register_static(&prom_info); -} - -device_init(prom_register_devices); - typedef struct RamDevice { SysBusDevice busdev; @@ -827,13 +806,6 @@ static TypeInfo ram_info = { .class_init = ram_class_init, }; -static void ram_register_devices(void) -{ - type_register_static(&ram_info); -} - -device_init(ram_register_devices); - static void cpu_devinit(const char *cpu_model, unsigned int id, uint64_t prom_addr, qemu_irq **cpu_irqs) { @@ -1865,6 +1837,14 @@ static QEMUMachine ss2_machine = { .use_scsi = 1, }; +static void sun4m_register_types(void) +{ + type_register_static(&idreg_info); + type_register_static(&afx_info); + type_register_static(&prom_info); + type_register_static(&ram_info); +} + static void ss2_machine_init(void) { qemu_register_machine(&ss5_machine); @@ -1881,4 +1861,5 @@ static void ss2_machine_init(void) qemu_register_machine(&ss2_machine); } +type_init(sun4m_register_types) machine_init(ss2_machine_init); diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c index 727532c..ebefa91 100644 --- a/hw/sun4m_iommu.c +++ b/hw/sun4m_iommu.c @@ -380,9 +380,9 @@ static TypeInfo iommu_info = { .class_init = iommu_class_init, }; -static void iommu_register_devices(void) +static void iommu_register_types(void) { type_register_static(&iommu_info); } -device_init(iommu_register_devices) +type_init(iommu_register_types) @@ -580,13 +580,6 @@ static TypeInfo ebus_info = { .class_init = ebus_class_init, }; -static void pci_ebus_register(void) -{ - type_register_static(&ebus_info); -} - -device_init(pci_ebus_register); - typedef struct PROMState { SysBusDevice busdev; MemoryRegion prom; @@ -664,13 +657,6 @@ static TypeInfo prom_info = { .class_init = prom_class_init, }; -static void prom_register_devices(void) -{ - type_register_static(&prom_info); -} - -device_init(prom_register_devices); - typedef struct RamDevice { @@ -728,13 +714,6 @@ static TypeInfo ram_info = { .class_init = ram_class_init, }; -static void ram_register_devices(void) -{ - type_register_static(&ram_info); -} - -device_init(ram_register_devices); - static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef) { CPUState *env; @@ -957,6 +936,13 @@ static QEMUMachine niagara_machine = { .max_cpus = 1, // XXX for now }; +static void sun4u_register_types(void) +{ + type_register_static(&ebus_info); + type_register_static(&prom_info); + type_register_static(&ram_info); +} + static void sun4u_machine_init(void) { qemu_register_machine(&sun4u_machine); @@ -964,4 +950,5 @@ static void sun4u_machine_init(void) qemu_register_machine(&niagara_machine); } +type_init(sun4u_register_types) machine_init(sun4u_machine_init); diff --git a/hw/sysbus.c b/hw/sysbus.c index 282060a..db4efcc 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -256,9 +256,9 @@ static TypeInfo sysbus_device_type_info = { .class_init = sysbus_device_class_init, }; -static void sysbus_register(void) +static void sysbus_register_types(void) { type_register_static(&sysbus_device_type_info); } -device_init(sysbus_register); +type_init(sysbus_register_types) @@ -664,9 +664,9 @@ static TypeInfo tcx_info = { .class_init = tcx_class_init, }; -static void tcx_register_devices(void) +static void tcx_register_types(void) { type_register_static(&tcx_info); } -device_init(tcx_register_devices) +type_init(tcx_register_types) diff --git a/hw/tmp105.c b/hw/tmp105.c index a3bdd91..8e8dbd9 100644 --- a/hw/tmp105.c +++ b/hw/tmp105.c @@ -245,9 +245,9 @@ static TypeInfo tmp105_info = { .class_init = tmp105_class_init, }; -static void tmp105_register_devices(void) +static void tmp105_register_types(void) { type_register_static(&tmp105_info); } -device_init(tmp105_register_devices) +type_init(tmp105_register_types) @@ -291,10 +291,10 @@ static TypeInfo tosa_ssp_info = { .class_init = tosa_ssp_class_init, }; -static void tosa_register_devices(void) +static void tosa_register_types(void) { type_register_static(&tosa_dac_info); type_register_static(&tosa_ssp_info); } -device_init(tosa_register_devices) +type_init(tosa_register_types) diff --git a/hw/tusb6010.c b/hw/tusb6010.c index 0ade670..5ba8da6 100644 --- a/hw/tusb6010.c +++ b/hw/tusb6010.c @@ -805,9 +805,9 @@ static TypeInfo tusb6010_info = { .class_init = tusb6010_class_init, }; -static void tusb6010_register_device(void) +static void tusb6010_register_types(void) { type_register_static(&tusb6010_info); } -device_init(tusb6010_register_device) +type_init(tusb6010_register_types) diff --git a/hw/twl92230.c b/hw/twl92230.c index 03fdccc..873dc8f 100644 --- a/hw/twl92230.c +++ b/hw/twl92230.c @@ -876,9 +876,9 @@ static TypeInfo twl92230_info = { .class_init = twl92230_class_init, }; -static void twl92230_register_devices(void) +static void twl92230_register_types(void) { type_register_static(&twl92230_info); } -device_init(twl92230_register_devices) +type_init(twl92230_register_types) diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 17d86aa..409bcd4 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -467,7 +467,7 @@ static TypeInfo pci_unin_internal_info = { .class_init = pci_unin_internal_class_init, }; -static void unin_register_devices(void) +static void unin_register_types(void) { type_register_static(&unin_main_pci_host_info); type_register_static(&u3_agp_pci_host_info); @@ -480,4 +480,4 @@ static void unin_register_devices(void) type_register_static(&pci_unin_internal_info); } -device_init(unin_register_devices) +type_init(unin_register_types) diff --git a/hw/usb-audio.c b/hw/usb-audio.c index cd589b7..fed1361 100644 --- a/hw/usb-audio.c +++ b/hw/usb-audio.c @@ -607,7 +607,7 @@ static int usb_audio_handle_data(USBDevice *dev, USBPacket *p) switch (p->pid) { case USB_TOKEN_OUT: - switch (p->devep) { + switch (p->ep->nr) { case 1: ret = usb_audio_handle_dataout(s, p); break; @@ -624,7 +624,7 @@ fail: if (ret == USB_RET_STALL && s->debug) { fprintf(stderr, "usb-audio: failed data transaction: " "pid 0x%x ep 0x%x len 0x%zx\n", - p->pid, p->devep, p->iov.size); + p->pid, p->ep->nr, p->iov.size); } return ret; } @@ -691,7 +691,6 @@ static void usb_audio_class_init(ObjectClass *klass, void *data) k->product_desc = "QEMU USB Audio Interface"; k->usb_desc = &desc_audio; k->init = usb_audio_initfn; - k->handle_packet = usb_generic_handle_packet; k->handle_reset = usb_audio_handle_reset; k->handle_control = usb_audio_handle_control; k->handle_data = usb_audio_handle_data; @@ -706,10 +705,10 @@ static TypeInfo usb_audio_info = { .class_init = usb_audio_class_init, }; -static void usb_audio_register_devices(void) +static void usb_audio_register_types(void) { type_register_static(&usb_audio_info); usb_legacy_register("usb-audio", "audio", NULL); } -device_init(usb_audio_register_devices) +type_init(usb_audio_register_types) diff --git a/hw/usb-bt.c b/hw/usb-bt.c index 90c3b0e..649bdcf 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -423,7 +423,7 @@ static int usb_bt_handle_data(USBDevice *dev, USBPacket *p) switch (p->pid) { case USB_TOKEN_IN: - switch (p->devep & 0xf) { + switch (p->ep->nr) { case USB_EVT_EP: ret = usb_bt_fifo_dequeue(&s->evt, p); break; @@ -442,7 +442,7 @@ static int usb_bt_handle_data(USBDevice *dev, USBPacket *p) break; case USB_TOKEN_OUT: - switch (p->devep & 0xf) { + switch (p->ep->nr) { case USB_ACL_EP: usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send, usb_bt_hci_acl_complete, p); @@ -535,7 +535,6 @@ static void usb_bt_class_initfn(ObjectClass *klass, void *data) uc->init = usb_bt_initfn; uc->product_desc = "QEMU BT dongle"; uc->usb_desc = &desc_bluetooth; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_bt_handle_reset; uc->handle_control = usb_bt_handle_control; uc->handle_data = usb_bt_handle_data; @@ -550,8 +549,9 @@ static TypeInfo bt_info = { .class_init = usb_bt_class_initfn, }; -static void usb_bt_register_devices(void) +static void usb_bt_register_types(void) { type_register_static(&bt_info); } -device_init(usb_bt_register_devices) + +type_init(usb_bt_register_types) diff --git a/hw/usb-bus.c b/hw/usb-bus.c index b753834..ae79a45 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -74,21 +74,21 @@ static int usb_device_init(USBDevice *dev) return 0; } -static void usb_device_handle_destroy(USBDevice *dev) +USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr) { USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); - if (klass->handle_destroy) { - klass->handle_destroy(dev); + if (klass->find_device) { + return klass->find_device(dev, addr); } + return NULL; } -int usb_device_handle_packet(USBDevice *dev, USBPacket *p) +static void usb_device_handle_destroy(USBDevice *dev) { USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); - if (klass->handle_packet) { - return klass->handle_packet(dev, p); + if (klass->handle_destroy) { + klass->handle_destroy(dev); } - return -ENOSYS; } void usb_device_cancel_packet(USBDevice *dev, USBPacket *p) @@ -586,9 +586,9 @@ static TypeInfo usb_device_type_info = { .class_init = usb_device_class_init, }; -static void usb_register_devices(void) +static void usb_register_types(void) { type_register_static(&usb_device_type_info); } -device_init(usb_register_devices); +type_init(usb_register_types) diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 881da30..0b2ac80 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -267,6 +267,7 @@ typedef struct CCIDBus { */ typedef struct USBCCIDState { USBDevice dev; + USBEndpoint *intr; CCIDBus bus; CCIDCardState *card; BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */ @@ -839,7 +840,7 @@ static void ccid_on_slot_change(USBCCIDState *s, bool full) s->bmSlotICCState |= SLOT_0_CHANGED_MASK; } s->notify_slot_change = true; - usb_wakeup(&s->dev); + usb_wakeup(s->intr); } static void ccid_write_data_block_error( @@ -995,7 +996,7 @@ static int ccid_handle_data(USBDevice *dev, USBPacket *p) break; case USB_TOKEN_IN: - switch (p->devep & 0xf) { + switch (p->ep->nr) { case CCID_BULK_IN_EP: if (!p->iov.size) { ret = USB_RET_NAK; @@ -1190,6 +1191,7 @@ static int ccid_initfn(USBDevice *dev) usb_desc_init(dev); qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL); + s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP); s->bus.qbus.allow_hotplug = 1; s->card = NULL; s->migration_state = MIGRATION_NONE; @@ -1320,7 +1322,6 @@ static void ccid_class_initfn(ObjectClass *klass, void *data) uc->init = ccid_initfn; uc->product_desc = "QEMU USB CCID"; uc->usb_desc = &desc_ccid; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = ccid_handle_reset; uc->handle_control = ccid_handle_control; uc->handle_data = ccid_handle_data; @@ -1354,10 +1355,11 @@ static TypeInfo ccid_card_type_info = { .class_init = ccid_card_class_init, }; -static void ccid_register_devices(void) +static void ccid_register_types(void) { type_register_static(&ccid_card_type_info); type_register_static(&ccid_info); usb_legacy_register(CCID_DEV_NAME, "ccid", NULL); } -device_init(ccid_register_devices) + +type_init(ccid_register_types) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 75ef71e..e699814 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -715,8 +715,8 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev) EHCIQueue *q, *tmp; QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) { - if (q->packet.owner == NULL || - q->packet.owner->dev != dev) { + if (!usb_packet_is_inflight(&q->packet) || + q->packet.ep->dev != dev) { continue; } ehci_free_queue(q); @@ -765,6 +765,11 @@ static void ehci_detach(USBPort *port) USBPort *companion = s->companion_ports[port->index]; companion->ops->detach(companion); companion->dev = NULL; + /* + * EHCI spec 4.2.2: "When a disconnect occurs... On the event, + * the port ownership is returned immediately to the EHCI controller." + */ + *portsc &= ~PORTSC_POWNER; return; } @@ -845,6 +850,26 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[], return 0; } +static USBDevice *ehci_find_device(EHCIState *ehci, uint8_t addr) +{ + USBDevice *dev; + USBPort *port; + int i; + + for (i = 0; i < NB_PORTS; i++) { + port = &ehci->ports[i]; + if (!(ehci->portsc[i] & PORTSC_PED)) { + DPRINTF("Port %d not enabled\n", i); + continue; + } + dev = usb_find_device(port, addr); + if (dev != NULL) { + return dev; + } + } + return NULL; +} + /* 4.1 host controller initialization */ static void ehci_reset(void *opaque) { @@ -883,7 +908,7 @@ static void ehci_reset(void *opaque) } if (devs[i] && devs[i]->attached) { usb_attach(&s->ports[i]); - usb_send_msg(devs[i], USB_MSG_RESET); + usb_device_reset(devs[i]); } } ehci_queues_rip_all(s); @@ -982,7 +1007,7 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val) if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) { trace_usb_ehci_port_reset(port, 0); if (dev && dev->attached) { - usb_reset(&s->ports[port]); + usb_port_reset(&s->ports[port]); *portsc &= ~PORTSC_CSC; } @@ -1331,10 +1356,9 @@ err: static int ehci_execute(EHCIQueue *q) { - USBPort *port; USBDevice *dev; + USBEndpoint *ep; int ret; - int i; int endp; int devadr; @@ -1364,33 +1388,18 @@ static int ehci_execute(EHCIQueue *q) endp = get_field(q->qh.epchar, QH_EPCHAR_EP); devadr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR); - ret = USB_RET_NODEV; + /* TODO: associating device with ehci port */ + dev = ehci_find_device(q->ehci, devadr); + ep = usb_ep_get(dev, q->pid, endp); - usb_packet_setup(&q->packet, q->pid, devadr, endp); + usb_packet_setup(&q->packet, q->pid, ep); usb_packet_map(&q->packet, &q->sgl); - // TO-DO: associating device with ehci port - for(i = 0; i < NB_PORTS; i++) { - port = &q->ehci->ports[i]; - dev = port->dev; - - if (!(q->ehci->portsc[i] &(PORTSC_CONNECT))) { - DPRINTF("Port %d, no exec, not connected(%08X)\n", - i, q->ehci->portsc[i]); - continue; - } - - ret = usb_handle_packet(dev, &q->packet); - - DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd " - "(total %d) endp %x ret %d\n", - q->qhaddr, q->qh.next, q->qtdaddr, q->pid, - q->packet.iov.size, q->tbytes, endp, ret); - - if (ret != USB_RET_NODEV) { - break; - } - } + ret = usb_handle_packet(dev, &q->packet); + DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd " + "(total %d) endp %x ret %d\n", + q->qhaddr, q->qh.next, q->qtdaddr, q->pid, + q->packet.iov.size, q->tbytes, endp, ret); if (ret > BUFF_SIZE) { fprintf(stderr, "ret from usb_handle_packet > BUFF_SIZE\n"); @@ -1406,10 +1415,10 @@ static int ehci_execute(EHCIQueue *q) static int ehci_process_itd(EHCIState *ehci, EHCIitd *itd) { - USBPort *port; USBDevice *dev; + USBEndpoint *ep; int ret; - uint32_t i, j, len, pid, dir, devaddr, endp; + uint32_t i, len, pid, dir, devaddr, endp; uint32_t pg, off, ptr1, ptr2, max, mult; dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION); @@ -1447,24 +1456,12 @@ static int ehci_process_itd(EHCIState *ehci, pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT; - usb_packet_setup(&ehci->ipacket, pid, devaddr, endp); + dev = ehci_find_device(ehci, devaddr); + ep = usb_ep_get(dev, pid, endp); + usb_packet_setup(&ehci->ipacket, pid, ep); usb_packet_map(&ehci->ipacket, &ehci->isgl); - ret = USB_RET_NODEV; - for (j = 0; j < NB_PORTS; j++) { - port = &ehci->ports[j]; - dev = port->dev; - - if (!(ehci->portsc[j] &(PORTSC_CONNECT))) { - continue; - } - - ret = usb_handle_packet(dev, &ehci->ipacket); - - if (ret != USB_RET_NODEV) { - break; - } - } + ret = usb_handle_packet(dev, &ehci->ipacket); usb_packet_unmap(&ehci->ipacket); qemu_sglist_destroy(&ehci->isgl); @@ -2376,12 +2373,13 @@ static int usb_ehci_initfn(PCIDevice *dev) return 0; } -static void ehci_register(void) +static void ehci_register_types(void) { type_register_static(&ehci_info); type_register_static(&ich9_ehci_info); } -device_init(ehci_register); + +type_init(ehci_register_types) /* * vim: expandtab ts=4 diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 3c4e45d..7fc0bd8 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -44,6 +44,7 @@ typedef struct USBHIDState { USBDevice dev; + USBEndpoint *intr; HIDState hid; } USBHIDState; @@ -360,7 +361,7 @@ static void usb_hid_changed(HIDState *hs) { USBHIDState *us = container_of(hs, USBHIDState, hid); - usb_wakeup(&us->dev); + usb_wakeup(us->intr); } static void usb_hid_handle_reset(USBDevice *dev) @@ -463,7 +464,7 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) switch (p->pid) { case USB_TOKEN_IN: - if (p->devep == 1) { + if (p->ep->nr == 1) { int64_t curtime = qemu_get_clock_ns(vm_clock); if (!hid_has_events(hs) && (!hs->idle || hs->next_idle_clock - curtime > 0)) { @@ -501,6 +502,7 @@ static int usb_hid_initfn(USBDevice *dev, int kind) USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); usb_desc_init(dev); + us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); hid_init(&us->hid, kind, usb_hid_changed); return 0; } @@ -557,7 +559,6 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data) { USBDeviceClass *uc = USB_DEVICE_CLASS(klass); - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_hid_handle_reset; uc->handle_control = usb_hid_handle_control; uc->handle_data = usb_hid_handle_data; @@ -621,7 +622,7 @@ static TypeInfo usb_keyboard_info = { .class_init = usb_keyboard_class_initfn, }; -static void usb_hid_register_devices(void) +static void usb_hid_register_types(void) { type_register_static(&usb_tablet_info); usb_legacy_register("usb-tablet", "tablet", NULL); @@ -630,4 +631,5 @@ static void usb_hid_register_devices(void) type_register_static(&usb_keyboard_info); usb_legacy_register("usb-kbd", "keyboard", NULL); } -device_init(usb_hid_register_devices) + +type_init(usb_hid_register_types) diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 956b020..a12856e 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -37,6 +37,7 @@ typedef struct USBHubPort { typedef struct USBHubState { USBDevice dev; + USBEndpoint *intr; USBHubPort ports[NUM_PORTS]; } USBHubState; @@ -163,7 +164,7 @@ static void usb_hub_attach(USBPort *port1) } else { port->wPortStatus &= ~PORT_STAT_LOW_SPEED; } - usb_wakeup(&s->dev); + usb_wakeup(s->intr); } static void usb_hub_detach(USBPort *port1) @@ -171,7 +172,7 @@ static void usb_hub_detach(USBPort *port1) USBHubState *s = port1->opaque; USBHubPort *port = &s->ports[port1->index]; - usb_wakeup(&s->dev); + usb_wakeup(s->intr); /* Let upstream know the device on this port is gone */ s->dev.port->ops->child_detach(s->dev.port, port1->dev); @@ -199,7 +200,7 @@ static void usb_hub_wakeup(USBPort *port1) if (port->wPortStatus & PORT_STAT_SUSPEND) { port->wPortChange |= PORT_STAT_C_SUSPEND; - usb_wakeup(&s->dev); + usb_wakeup(s->intr); } } @@ -220,6 +221,26 @@ static void usb_hub_complete(USBPort *port, USBPacket *packet) s->dev.port->ops->complete(s->dev.port, packet); } +static USBDevice *usb_hub_find_device(USBDevice *dev, uint8_t addr) +{ + USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubPort *port; + USBDevice *downstream; + int i; + + for (i = 0; i < NUM_PORTS; i++) { + port = &s->ports[i]; + if (!(port->wPortStatus & PORT_STAT_ENABLE)) { + continue; + } + downstream = usb_find_device(&port->port, addr); + if (downstream != NULL) { + return downstream; + } + } + return NULL; +} + static void usb_hub_handle_reset(USBDevice *dev) { USBHubState *s = DO_UPCAST(USBHubState, dev, dev); @@ -305,7 +326,7 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p, break; case PORT_RESET: if (dev && dev->attached) { - usb_send_msg(dev, USB_MSG_RESET); + usb_device_reset(dev); port->wPortChange |= PORT_STAT_C_RESET; /* set enable bit */ port->wPortStatus |= PORT_STAT_ENABLE; @@ -396,7 +417,7 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) switch(p->pid) { case USB_TOKEN_IN: - if (p->devep == 1) { + if (p->ep->nr == 1) { USBHubPort *port; unsigned int status; uint8_t buf[4]; @@ -435,44 +456,6 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) return ret; } -static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p) -{ - USBHubPort *port; - USBDevice *dev; - int i, ret; - - for(i = 0; i < NUM_PORTS; i++) { - port = &s->ports[i]; - dev = port->port.dev; - if (dev && dev->attached && (port->wPortStatus & PORT_STAT_ENABLE)) { - ret = usb_handle_packet(dev, p); - if (ret != USB_RET_NODEV) { - return ret; - } - } - } - return USB_RET_NODEV; -} - -static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p) -{ - USBHubState *s = (USBHubState *)dev; - -#if defined(DEBUG) && 0 - printf("usb_hub: pid=0x%x\n", pid); -#endif - if (dev->state == USB_STATE_DEFAULT && - dev->addr != 0 && - p->devaddr != dev->addr && - (p->pid == USB_TOKEN_SETUP || - p->pid == USB_TOKEN_OUT || - p->pid == USB_TOKEN_IN)) { - /* broadcast the packet to the devices */ - return usb_hub_broadcast_packet(s, p); - } - return usb_generic_handle_packet(dev, p); -} - static void usb_hub_handle_destroy(USBDevice *dev) { USBHubState *s = (USBHubState *)dev; @@ -499,6 +482,7 @@ static int usb_hub_initfn(USBDevice *dev) int i; usb_desc_init(dev); + s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); for (i = 0; i < NUM_PORTS; i++) { port = &s->ports[i]; usb_register_port(usb_bus_from_device(dev), @@ -541,7 +525,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data) uc->init = usb_hub_initfn; uc->product_desc = "QEMU USB Hub"; uc->usb_desc = &desc_hub; - uc->handle_packet = usb_hub_handle_packet; + uc->find_device = usb_hub_find_device; uc->handle_reset = usb_hub_handle_reset; uc->handle_control = usb_hub_handle_control; uc->handle_data = usb_hub_handle_data; @@ -557,8 +541,9 @@ static TypeInfo hub_info = { .class_init = usb_hub_class_initfn, }; -static void usb_hub_register_devices(void) +static void usb_hub_register_types(void) { type_register_static(&hub_info); } -device_init(usb_hub_register_devices) + +type_init(usb_hub_register_types) diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 6153376..c933efe 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -341,7 +341,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) uint32_t tag; int ret = 0; struct usb_msd_cbw cbw; - uint8_t devep = p->devep; + uint8_t devep = p->ep->nr; switch (p->pid) { case USB_TOKEN_OUT: @@ -651,7 +651,6 @@ static void usb_msd_class_initfn(ObjectClass *klass, void *data) uc->init = usb_msd_initfn; uc->product_desc = "QEMU USB MSD"; uc->usb_desc = &desc; - uc->handle_packet = usb_generic_handle_packet; uc->cancel_packet = usb_msd_cancel_io; uc->handle_attach = usb_desc_attach; uc->handle_reset = usb_msd_handle_reset; @@ -669,9 +668,10 @@ static TypeInfo msd_info = { .class_init = usb_msd_class_initfn, }; -static void usb_msd_register_devices(void) +static void usb_msd_register_types(void) { type_register_static(&msd_info); usb_legacy_register("usb-storage", "disk", usb_msd_init); } -device_init(usb_msd_register_devices) + +type_init(usb_msd_register_types) diff --git a/hw/usb-musb.c b/hw/usb-musb.c index 4f528d2..820907a 100644 --- a/hw/usb-musb.c +++ b/hw/usb-musb.c @@ -605,6 +605,8 @@ static int musb_timeout(int ttype, int speed, int val) static void musb_packet(MUSBState *s, MUSBEndPoint *ep, int epnum, int pid, int len, USBCallback cb, int dir) { + USBDevice *dev; + USBEndpoint *uep; int ret; int idx = epnum && dir; int ttype; @@ -622,16 +624,14 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep, ep->delayed_cb[dir] = cb; /* A wild guess on the FADDR semantics... */ - usb_packet_setup(&ep->packey[dir].p, pid, ep->faddr[idx], - ep->type[idx] & 0xf); + dev = usb_find_device(&s->port, ep->faddr[idx]); + uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf); + usb_packet_setup(&ep->packey[dir].p, pid, uep); usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len); ep->packey[dir].ep = ep; ep->packey[dir].dir = dir; - if (s->port.dev) - ret = usb_handle_packet(s->port.dev, &ep->packey[dir].p); - else - ret = USB_RET_NODEV; + ret = usb_handle_packet(dev, &ep->packey[dir].p); if (ret == USB_RET_ASYNC) { ep->status[dir] = len; @@ -812,8 +812,8 @@ static void musb_async_cancel_device(MUSBState *s, USBDevice *dev) for (ep = 0; ep < 16; ep++) { for (dir = 0; dir < 2; dir++) { - if (s->ep[ep].packey[dir].p.owner == NULL || - s->ep[ep].packey[dir].p.owner->dev != dev) { + if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) || + s->ep[ep].packey[dir].p.ep->dev != dev) { continue; } usb_cancel_packet(&s->ep[ep].packey[dir].p); @@ -1310,7 +1310,7 @@ static void musb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) s->power = (value & 0xef) | (s->power & 0x10); /* MGC_M_POWER_RESET is also read-only in Peripheral Mode */ if ((value & MGC_M_POWER_RESET) && s->port.dev) { - usb_send_msg(s->port.dev, USB_MSG_RESET); + usb_device_reset(s->port.dev); /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set. */ if ((value & MGC_M_POWER_HSENAB) && s->port.dev->speed == USB_SPEED_HIGH) diff --git a/hw/usb-net.c b/hw/usb-net.c index e211141..49d5d4d 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1210,7 +1210,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p) switch(p->pid) { case USB_TOKEN_IN: - switch (p->devep) { + switch (p->ep->nr) { case 1: ret = usb_net_handle_statusin(s, p); break; @@ -1225,7 +1225,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p) break; case USB_TOKEN_OUT: - switch (p->devep) { + switch (p->ep->nr) { case 2: ret = usb_net_handle_dataout(s, p); break; @@ -1243,7 +1243,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p) if (ret == USB_RET_STALL) fprintf(stderr, "usbnet: failed data transaction: " "pid 0x%x ep 0x%x len 0x%zx\n", - p->pid, p->devep, p->iov.size); + p->pid, p->ep->nr, p->iov.size); return ret; } @@ -1398,7 +1398,6 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data) uc->init = usb_net_initfn; uc->product_desc = "QEMU USB Network Interface"; uc->usb_desc = &desc_net; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_net_handle_reset; uc->handle_control = usb_net_handle_control; uc->handle_data = usb_net_handle_data; @@ -1415,9 +1414,10 @@ static TypeInfo net_info = { .class_init = usb_net_class_initfn, }; -static void usb_net_register_devices(void) +static void usb_net_register_types(void) { type_register_static(&net_info); usb_legacy_register("usb-net", "net", usb_net_init); } -device_init(usb_net_register_devices) + +type_init(usb_net_register_types) diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 425030f..7aa19fe 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -408,6 +408,23 @@ static void ohci_child_detach(USBPort *port1, USBDevice *child) ohci_async_cancel_device(s, child); } +static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr) +{ + USBDevice *dev; + int i; + + for (i = 0; i < ohci->num_ports; i++) { + if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) { + continue; + } + dev = usb_find_device(&ohci->rhport[i].port, addr); + if (dev != NULL) { + return dev; + } + } + return NULL; +} + /* Reset the controller */ static void ohci_reset(void *opaque) { @@ -449,7 +466,7 @@ static void ohci_reset(void *opaque) port = &ohci->rhport[i]; port->ctrl = 0; if (port->port.dev && port->port.dev->attached) { - usb_reset(&port->port); + usb_port_reset(&port->port); } } if (ohci->async_td) { @@ -640,6 +657,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, int ret; int i; USBDevice *dev; + USBEndpoint *ep; struct ohci_iso_td iso_td; uint32_t addr; uint16_t starting_frame; @@ -779,20 +797,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, if (completion) { ret = ohci->usb_packet.result; } else { - ret = USB_RET_NODEV; - for (i = 0; i < ohci->num_ports; i++) { - dev = ohci->rhport[i].port.dev; - if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) - continue; - usb_packet_setup(&ohci->usb_packet, pid, - OHCI_BM(ed->flags, ED_FA), - OHCI_BM(ed->flags, ED_EN)); - usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); - ret = usb_handle_packet(dev, &ohci->usb_packet); - if (ret != USB_RET_NODEV) - break; - } - + dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); + ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); + usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); + ret = usb_handle_packet(dev, &ohci->usb_packet); if (ret == USB_RET_ASYNC) { return 1; } @@ -880,6 +889,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) int ret; int i; USBDevice *dev; + USBEndpoint *ep; struct ohci_td td; uint32_t addr; int flag_r; @@ -972,31 +982,22 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) ohci->async_td = 0; ohci->async_complete = 0; } else { - ret = USB_RET_NODEV; - for (i = 0; i < ohci->num_ports; i++) { - dev = ohci->rhport[i].port.dev; - if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) - continue; - - if (ohci->async_td) { - /* ??? The hardware should allow one active packet per - endpoint. We only allow one active packet per controller. - This should be sufficient as long as devices respond in a - timely manner. - */ + if (ohci->async_td) { + /* ??? The hardware should allow one active packet per + endpoint. We only allow one active packet per controller. + This should be sufficient as long as devices respond in a + timely manner. + */ #ifdef DEBUG_PACKET - DPRINTF("Too many pending packets\n"); + DPRINTF("Too many pending packets\n"); #endif - return 1; - } - usb_packet_setup(&ohci->usb_packet, pid, - OHCI_BM(ed->flags, ED_FA), - OHCI_BM(ed->flags, ED_EN)); - usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); - ret = usb_handle_packet(dev, &ohci->usb_packet); - if (ret != USB_RET_NODEV) - break; + return 1; } + dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); + ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); + usb_packet_setup(&ohci->usb_packet, pid, ep); + usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); + ret = usb_handle_packet(dev, &ohci->usb_packet); #ifdef DEBUG_PACKET DPRINTF("ret=%d\n", ret); #endif @@ -1435,7 +1436,7 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) { DPRINTF("usb-ohci: port %d: RESET\n", portnum); - usb_send_msg(port->port.dev, USB_MSG_RESET); + usb_device_reset(port->port.dev); port->ctrl &= ~OHCI_PORT_PRS; /* ??? Should this also set OHCI_PORT_PESC. */ port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC; @@ -1708,8 +1709,8 @@ static void ohci_mem_write(void *opaque, static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) { if (ohci->async_td && - ohci->usb_packet.owner != NULL && - ohci->usb_packet.owner->dev == dev) { + usb_packet_is_inflight(&ohci->usb_packet) && + ohci->usb_packet.ep->dev == dev) { usb_cancel_packet(&ohci->usb_packet); ohci->async_td = 0; } @@ -1886,9 +1887,10 @@ static TypeInfo ohci_sysbus_info = { .class_init = ohci_sysbus_class_init, }; -static void ohci_register(void) +static void ohci_register_types(void) { type_register_static(&ohci_pci_info); type_register_static(&ohci_sysbus_info); } -device_init(ohci_register); + +type_init(ohci_register_types) diff --git a/hw/usb-serial.c b/hw/usb-serial.c index c2cb6d2..52676e8 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -353,7 +353,7 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) { USBSerialState *s = (USBSerialState *)dev; int i, ret = 0; - uint8_t devep = p->devep; + uint8_t devep = p->ep->nr; struct iovec *iov; uint8_t header[2]; int first_len, len; @@ -583,7 +583,6 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data) uc->init = usb_serial_initfn; uc->product_desc = "QEMU USB Serial"; uc->usb_desc = &desc_serial; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_serial_handle_reset; uc->handle_control = usb_serial_handle_control; uc->handle_data = usb_serial_handle_data; @@ -612,7 +611,6 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data) uc->init = usb_serial_initfn; uc->product_desc = "QEMU USB Braille"; uc->usb_desc = &desc_braille; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_serial_handle_reset; uc->handle_control = usb_serial_handle_control; uc->handle_data = usb_serial_handle_data; @@ -628,11 +626,12 @@ static TypeInfo braille_info = { .class_init = usb_braille_class_initfn, }; -static void usb_serial_register_devices(void) +static void usb_serial_register_types(void) { type_register_static(&serial_info); usb_legacy_register("usb-serial", "serial", usb_serial_init); type_register_static(&braille_info); usb_legacy_register("usb-braille", "braille", usb_braille_init); } -device_init(usb_serial_register_devices) + +type_init(usb_serial_register_types) diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index cddcc89..2280dc7 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -73,7 +73,7 @@ #define FRAME_TIMER_FREQ 1000 -#define FRAME_MAX_LOOPS 100 +#define FRAME_MAX_LOOPS 256 #define NB_PORTS 2 @@ -94,15 +94,6 @@ static const char *pid2str(int pid) #define DPRINTF(...) #endif -#ifdef DEBUG_DUMP_DATA -static void dump_data(USBPacket *p, int ret) -{ - iov_hexdump(p->iov.iov, p->iov.niov, stderr, "uhci", ret); -} -#else -static void dump_data(USBPacket *p, int ret) {} -#endif - typedef struct UHCIState UHCIState; /* @@ -245,8 +236,8 @@ static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev) UHCIAsync *curr, *n; QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) { - if (curr->packet.owner == NULL || - curr->packet.owner->dev != dev) { + if (!usb_packet_is_inflight(&curr->packet) || + curr->packet.ep->dev != dev) { continue; } uhci_async_unlink(s, curr); @@ -342,7 +333,7 @@ static void uhci_reset(void *opaque) port = &s->ports[i]; port->ctrl = 0x0080; if (port->port.dev && port->port.dev->attached) { - usb_reset(&port->port); + usb_port_reset(&port->port); } } @@ -440,16 +431,12 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val) } if (val & UHCI_CMD_GRESET) { UHCIPort *port; - USBDevice *dev; int i; /* send reset on the USB bus */ for(i = 0; i < NB_PORTS; i++) { port = &s->ports[i]; - dev = port->port.dev; - if (dev && dev->attached) { - usb_send_msg(dev, USB_MSG_RESET); - } + usb_device_reset(port->port.dev); } uhci_reset(s); return; @@ -491,7 +478,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val) /* port reset */ if ( (val & UHCI_PORT_RESET) && !(port->ctrl & UHCI_PORT_RESET) ) { - usb_send_msg(dev, USB_MSG_RESET); + usb_device_reset(dev); } } port->ctrl &= UHCI_PORT_READ_ONLY; @@ -647,30 +634,22 @@ static void uhci_wakeup(USBPort *port1) } } -static int uhci_broadcast_packet(UHCIState *s, USBPacket *p) +static USBDevice *uhci_find_device(UHCIState *s, uint8_t addr) { - int i, ret; - - DPRINTF("uhci: packet enter. pid %s addr 0x%02x ep %d len %zd\n", - pid2str(p->pid), p->devaddr, p->devep, p->iov.size); - if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP) - dump_data(p, 0); + USBDevice *dev; + int i; - ret = USB_RET_NODEV; - for (i = 0; i < NB_PORTS && ret == USB_RET_NODEV; i++) { + for (i = 0; i < NB_PORTS; i++) { UHCIPort *port = &s->ports[i]; - USBDevice *dev = port->port.dev; - - if (dev && dev->attached && (port->ctrl & UHCI_PORT_EN)) { - ret = usb_handle_packet(dev, p); + if (!(port->ctrl & UHCI_PORT_EN)) { + continue; + } + dev = usb_find_device(&port->port, addr); + if (dev != NULL) { + return dev; } } - - DPRINTF("uhci: packet exit. ret %d len %zd\n", ret, p->iov.size); - if (p->pid == USB_TOKEN_IN && ret > 0) - dump_data(p, ret); - - return ret; + return NULL; } static void uhci_async_complete(USBPort *port, USBPacket *packet); @@ -782,6 +761,8 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in int len = 0, max_len; uint8_t pid, isoc; uint32_t token; + USBDevice *dev; + USBEndpoint *ep; /* Is active ? */ if (!(td->ctrl & TD_CTRL_ACTIVE)) @@ -826,21 +807,22 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in max_len = ((td->token >> 21) + 1) & 0x7ff; pid = td->token & 0xff; - usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f, - (td->token >> 15) & 0xf); + dev = uhci_find_device(s, (td->token >> 8) & 0x7f); + ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf); + usb_packet_setup(&async->packet, pid, ep); qemu_sglist_add(&async->sgl, td->buffer, max_len); usb_packet_map(&async->packet, &async->sgl); switch(pid) { case USB_TOKEN_OUT: case USB_TOKEN_SETUP: - len = uhci_broadcast_packet(s, &async->packet); + len = usb_handle_packet(dev, &async->packet); if (len >= 0) len = max_len; break; case USB_TOKEN_IN: - len = uhci_broadcast_packet(s, &async->packet); + len = usb_handle_packet(dev, &async->packet); break; default: @@ -942,7 +924,7 @@ static int qhdb_insert(QhDb *db, uint32_t addr) static void uhci_process_frame(UHCIState *s) { uint32_t frame_addr, link, old_td_ctrl, val, int_mask; - uint32_t curr_qh; + uint32_t curr_qh, td_count = 0, bytes_count = 0; int cnt, ret; UHCI_TD td; UHCI_QH qh; @@ -967,13 +949,26 @@ static void uhci_process_frame(UHCIState *s) if (qhdb_insert(&qhdb, link)) { /* * We're going in circles. Which is not a bug because - * HCD is allowed to do that as part of the BW management. - * In our case though it makes no sense to spin here. Sync transations - * are already done, and async completion handler will re-process - * the frame when something is ready. + * HCD is allowed to do that as part of the BW management. + * + * Stop processing here if + * (a) no transaction has been done since we've been + * here last time, or + * (b) we've reached the usb 1.1 bandwidth, which is + * 1280 bytes/frame. */ DPRINTF("uhci: detected loop. qh 0x%x\n", link); - break; + if (td_count == 0) { + DPRINTF("uhci: no transaction last round, stop\n"); + break; + } else if (bytes_count >= 1280) { + DPRINTF("uhci: bandwidth limit reached, stop\n"); + break; + } else { + td_count = 0; + qhdb_reset(&qhdb); + qhdb_insert(&qhdb, link); + } } pci_dma_read(&s->dev, link & ~0xf, &qh, sizeof(qh)); @@ -1033,6 +1028,8 @@ static void uhci_process_frame(UHCIState *s) link, td.link, td.ctrl, td.token, curr_qh); link = td.link; + td_count++; + bytes_count += (td.ctrl & 0x7ff) + 1; if (curr_qh) { /* update QH element link */ @@ -1321,7 +1318,7 @@ static TypeInfo ich9_uhci3_info = { .class_init = ich9_uhci3_class_init, }; -static void uhci_register(void) +static void uhci_register_types(void) { type_register_static(&piix3_uhci_info); type_register_static(&piix4_uhci_info); @@ -1330,7 +1327,8 @@ static void uhci_register(void) type_register_static(&ich9_uhci2_info); type_register_static(&ich9_uhci3_info); } -device_init(uhci_register); + +type_init(uhci_register_types) void usb_uhci_piix3_init(PCIBus *bus, int devfn) { diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c index 14de14d..197e2dc 100644 --- a/hw/usb-wacom.c +++ b/hw/usb-wacom.c @@ -306,7 +306,7 @@ static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p) switch (p->pid) { case USB_TOKEN_IN: - if (p->devep == 1) { + if (p->ep->nr == 1) { if (!(s->changed || s->idle)) return USB_RET_NAK; s->changed = 0; @@ -357,7 +357,6 @@ static void usb_wacom_class_init(ObjectClass *klass, void *data) uc->product_desc = "QEMU PenPartner Tablet"; uc->usb_desc = &desc_wacom; uc->init = usb_wacom_initfn; - uc->handle_packet = usb_generic_handle_packet; uc->handle_reset = usb_wacom_handle_reset; uc->handle_control = usb_wacom_handle_control; uc->handle_data = usb_wacom_handle_data; @@ -373,9 +372,10 @@ static TypeInfo wacom_info = { .class_init = usb_wacom_class_init, }; -static void usb_wacom_register_devices(void) +static void usb_wacom_register_types(void) { type_register_static(&wacom_info); usb_legacy_register("usb-wacom-tablet", "wacom-tablet", NULL); } -device_init(usb_wacom_register_devices) + +type_init(usb_wacom_register_types) diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c index 37e887c..008b0b5 100644 --- a/hw/usb-xhci.c +++ b/hw/usb-xhci.c @@ -307,7 +307,8 @@ typedef struct XHCIState XHCIState; typedef struct XHCITransfer { XHCIState *xhci; USBPacket packet; - bool running; + bool running_async; + bool running_retry; bool cancelled; bool complete; bool backgrounded; @@ -338,6 +339,7 @@ typedef struct XHCIEPContext { unsigned int next_xfer; unsigned int comp_xfer; XHCITransfer transfers[TD_QUEUE]; + XHCITransfer *retry; bool bg_running; bool bg_updating; unsigned int next_bg; @@ -420,6 +422,60 @@ typedef struct XHCIEvRingSeg { uint32_t rsvd; } XHCIEvRingSeg; +#ifdef DEBUG_XHCI +static const char *TRBType_names[] = { + [TRB_RESERVED] = "TRB_RESERVED", + [TR_NORMAL] = "TR_NORMAL", + [TR_SETUP] = "TR_SETUP", + [TR_DATA] = "TR_DATA", + [TR_STATUS] = "TR_STATUS", + [TR_ISOCH] = "TR_ISOCH", + [TR_LINK] = "TR_LINK", + [TR_EVDATA] = "TR_EVDATA", + [TR_NOOP] = "TR_NOOP", + [CR_ENABLE_SLOT] = "CR_ENABLE_SLOT", + [CR_DISABLE_SLOT] = "CR_DISABLE_SLOT", + [CR_ADDRESS_DEVICE] = "CR_ADDRESS_DEVICE", + [CR_CONFIGURE_ENDPOINT] = "CR_CONFIGURE_ENDPOINT", + [CR_EVALUATE_CONTEXT] = "CR_EVALUATE_CONTEXT", + [CR_RESET_ENDPOINT] = "CR_RESET_ENDPOINT", + [CR_STOP_ENDPOINT] = "CR_STOP_ENDPOINT", + [CR_SET_TR_DEQUEUE] = "CR_SET_TR_DEQUEUE", + [CR_RESET_DEVICE] = "CR_RESET_DEVICE", + [CR_FORCE_EVENT] = "CR_FORCE_EVENT", + [CR_NEGOTIATE_BW] = "CR_NEGOTIATE_BW", + [CR_SET_LATENCY_TOLERANCE] = "CR_SET_LATENCY_TOLERANCE", + [CR_GET_PORT_BANDWIDTH] = "CR_GET_PORT_BANDWIDTH", + [CR_FORCE_HEADER] = "CR_FORCE_HEADER", + [CR_NOOP] = "CR_NOOP", + [ER_TRANSFER] = "ER_TRANSFER", + [ER_COMMAND_COMPLETE] = "ER_COMMAND_COMPLETE", + [ER_PORT_STATUS_CHANGE] = "ER_PORT_STATUS_CHANGE", + [ER_BANDWIDTH_REQUEST] = "ER_BANDWIDTH_REQUEST", + [ER_DOORBELL] = "ER_DOORBELL", + [ER_HOST_CONTROLLER] = "ER_HOST_CONTROLLER", + [ER_DEVICE_NOTIFICATION] = "ER_DEVICE_NOTIFICATION", + [ER_MFINDEX_WRAP] = "ER_MFINDEX_WRAP", + [CR_VENDOR_VIA_CHALLENGE_RESPONSE] = "CR_VENDOR_VIA_CHALLENGE_RESPONSE", + [CR_VENDOR_NEC_FIRMWARE_REVISION] = "CR_VENDOR_NEC_FIRMWARE_REVISION", + [CR_VENDOR_NEC_CHALLENGE_RESPONSE] = "CR_VENDOR_NEC_CHALLENGE_RESPONSE", +}; + +static const char *lookup_name(uint32_t index, const char **list, uint32_t llen) +{ + if (index >= llen || list[index] == NULL) { + return "???"; + } + return list[index]; +} + +static const char *trb_name(XHCITRB *trb) +{ + return lookup_name(TRB_TYPE(*trb), TRBType_names, + ARRAY_SIZE(TRBType_names)); +} +#endif + static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid); @@ -487,8 +543,9 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) } ev_trb.control = cpu_to_le32(ev_trb.control); - DPRINTF("xhci_write_event(): [%d] %016"PRIx64" %08x %08x\n", - xhci->er_ep_idx, ev_trb.parameter, ev_trb.status, ev_trb.control); + DPRINTF("xhci_write_event(): [%d] %016"PRIx64" %08x %08x %s\n", + xhci->er_ep_idx, ev_trb.parameter, ev_trb.status, ev_trb.control, + trb_name(&ev_trb)); addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; cpu_physical_memory_write(addr, (uint8_t *) &ev_trb, TRB_SIZE); @@ -649,8 +706,9 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, le32_to_cpus(&trb->control); DPRINTF("xhci: TRB fetched [" TARGET_FMT_plx "]: " - "%016" PRIx64 " %08x %08x\n", - ring->dequeue, trb->parameter, trb->status, trb->control); + "%016" PRIx64 " %08x %08x %s\n", + ring->dequeue, trb->parameter, trb->status, trb->control, + trb_name(trb)); if ((trb->control & TRB_C) != ring->ccs) { return 0; @@ -859,12 +917,17 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, xferi = epctx->next_xfer; for (i = 0; i < TD_QUEUE; i++) { XHCITransfer *t = &epctx->transfers[xferi]; - if (t->running) { + if (t->running_async) { + usb_cancel_packet(&t->packet); + t->running_async = 0; t->cancelled = 1; - /* libusb_cancel_transfer(t->usbxfer) */ DPRINTF("xhci: cancelling transfer %d, waiting for it to complete...\n", i); killed++; } + if (t->running_retry) { + t->running_retry = 0; + epctx->retry = NULL; + } if (t->backgrounded) { t->backgrounded = 0; } @@ -885,9 +948,10 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, xferi = epctx->next_bg; for (i = 0; i < BG_XFERS; i++) { XHCITransfer *t = &epctx->bg_transfers[xferi]; - if (t->running) { + if (t->running_async) { + usb_cancel_packet(&t->packet); + t->running_async = 0; t->cancelled = 1; - /* libusb_cancel_transfer(t->usbxfer); */ DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i); killed++; } @@ -1336,27 +1400,37 @@ static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer, } #endif -static int xhci_setup_packet(XHCITransfer *xfer, XHCIPort *port, int ep) +static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) { - usb_packet_setup(&xfer->packet, - xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT, - xfer->xhci->slots[xfer->slotid-1].devaddr, - ep & 0x7f); + USBEndpoint *ep; + int dir; + + dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; + ep = usb_ep_get(dev, dir, xfer->epid >> 1); + usb_packet_setup(&xfer->packet, dir, ep); usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length); DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", - xfer->packet.pid, xfer->packet.devaddr, xfer->packet.devep); + xfer->packet.pid, dev->addr, ep->nr); return 0; } static int xhci_complete_packet(XHCITransfer *xfer, int ret) { if (ret == USB_RET_ASYNC) { - xfer->running = 1; + xfer->running_async = 1; + xfer->running_retry = 0; + xfer->complete = 0; + xfer->cancelled = 0; + return 0; + } else if (ret == USB_RET_NAK) { + xfer->running_async = 0; + xfer->running_retry = 1; xfer->complete = 0; xfer->cancelled = 0; return 0; } else { - xfer->running = 0; + xfer->running_async = 0; + xfer->running_retry = 0; xfer->complete = 1; } @@ -1385,6 +1459,14 @@ static int xhci_complete_packet(XHCITransfer *xfer, int ret) return 0; } +static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) +{ + if (!(port->portsc & PORTSC_PED)) { + return NULL; + } + return usb_find_device(&port->port, addr); +} + static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) { XHCITRB *trb_setup, *trb_status; @@ -1444,7 +1526,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) xfer->data_length = wLength; port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; - dev = port->port.dev; + dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); if (!dev) { fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, xhci->slots[xfer->slotid-1].port); @@ -1454,7 +1536,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) xfer->in_xfer = bmRequestType & USB_DIR_IN; xfer->iso_xfer = false; - xhci_setup_packet(xfer, port, 0); + xhci_setup_packet(xfer, dev); if (!xfer->in_xfer) { xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0); } @@ -1463,7 +1545,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) wValue, wIndex, wLength, xfer->data); xhci_complete_packet(xfer, ret); - if (!xfer->running) { + if (!xfer->running_async && !xfer->running_retry) { xhci_kick_ep(xhci, xfer->slotid, xfer->epid); } return 0; @@ -1476,12 +1558,8 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx int ret; DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); - uint8_t ep = xfer->epid>>1; xfer->in_xfer = epctx->type>>2; - if (xfer->in_xfer) { - ep |= 0x80; - } if (xfer->data && xfer->data_alloced < xfer->data_length) { xfer->data_alloced = 0; @@ -1502,14 +1580,14 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx } port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; - dev = port->port.dev; + dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); if (!dev) { fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, xhci->slots[xfer->slotid-1].port); return -1; } - xhci_setup_packet(xfer, port, ep); + xhci_setup_packet(xfer, dev); switch(epctx->type) { case ET_INTR_OUT: @@ -1522,8 +1600,9 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx FIXME(); break; default: - fprintf(stderr, "xhci: unknown or unhandled EP type %d (ep %02x)\n", - epctx->type, ep); + fprintf(stderr, "xhci: unknown or unhandled EP " + "(type %d, in %d, ep %02x)\n", + epctx->type, xfer->in_xfer, xfer->epid); return -1; } @@ -1533,7 +1612,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx ret = usb_handle_packet(dev, &xfer->packet); xhci_complete_packet(xfer, ret); - if (!xfer->running) { + if (!xfer->running_async && !xfer->running_retry) { xhci_kick_ep(xhci, xfer->slotid, xfer->epid); } return 0; @@ -1604,6 +1683,25 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid return; } + if (epctx->retry) { + /* retry nak'ed transfer */ + XHCITransfer *xfer = epctx->retry; + int result; + + DPRINTF("xhci: retry nack'ed transfer ...\n"); + assert(xfer->running_retry); + xhci_setup_packet(xfer, xfer->packet.ep->dev); + result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); + if (result == USB_RET_NAK) { + DPRINTF("xhci: ... xfer still nacked\n"); + return; + } + DPRINTF("xhci: ... result %d\n", result); + xhci_complete_packet(xfer, result); + assert(!xfer->running_retry); + epctx->retry = NULL; + } + if (epctx->state == EP_HALTED) { DPRINTF("xhci: ep halted, not running schedule\n"); return; @@ -1613,9 +1711,13 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid while (1) { XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer]; - if (xfer->running || xfer->backgrounded) { - DPRINTF("xhci: ep is busy\n"); + if (xfer->running_async || xfer->running_retry || xfer->backgrounded) { + DPRINTF("xhci: ep is busy (#%d,%d,%d,%d)\n", + epctx->next_xfer, xfer->running_async, + xfer->running_retry, xfer->backgrounded); break; + } else { + DPRINTF("xhci: ep: using #%d\n", epctx->next_xfer); } length = xhci_ring_chain_length(xhci, &epctx->ring); if (length < 0) { @@ -1658,10 +1760,19 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid } } + if (epctx->state == EP_HALTED) { + DPRINTF("xhci: ep halted, stopping schedule\n"); + break; + } + if (xfer->running_retry) { + DPRINTF("xhci: xfer nacked, stopping schedule\n"); + epctx->retry = xfer; + break; + } + /* * Qemu usb can't handle multiple in-flight xfers. - * Also xfers might be finished here already, - * possibly with an error. Stop here for now. + * Stop here for now. */ break; } @@ -2346,9 +2457,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) /* write-1-to-start bits */ if (val & PORTSC_PR) { DPRINTF("xhci: port %d reset\n", port); - if (xhci->ports[port].port.dev) { - usb_send_msg(xhci->ports[port].port.dev, USB_MSG_RESET); - } + usb_device_reset(xhci->ports[port].port.dev); portsc |= PORTSC_PRC | PORTSC_PED; } xhci->ports[port].portsc = portsc; @@ -2633,6 +2742,26 @@ static void xhci_detach(USBPort *usbport) xhci_update_port(xhci, port, 1); } +static void xhci_wakeup(USBPort *usbport) +{ + XHCIState *xhci = usbport->opaque; + XHCIPort *port = &xhci->ports[usbport->index]; + int nr = port->port.index + 1; + XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; + uint32_t pls; + + pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK; + if (pls != 3) { + return; + } + port->portsc |= 0xf << PORTSC_PLS_SHIFT; + if (port->portsc & PORTSC_PLC) { + return; + } + port->portsc |= PORTSC_PLC; + xhci_event(xhci, &ev); +} + static void xhci_complete(USBPort *port, USBPacket *packet) { XHCITransfer *xfer = container_of(packet, XHCITransfer, packet); @@ -2649,11 +2778,53 @@ static void xhci_child_detach(USBPort *port, USBDevice *child) static USBPortOps xhci_port_ops = { .attach = xhci_attach, .detach = xhci_detach, + .wakeup = xhci_wakeup, .complete = xhci_complete, .child_detach = xhci_child_detach, }; +static int xhci_find_slotid(XHCIState *xhci, USBDevice *dev) +{ + XHCISlot *slot; + int slotid; + + for (slotid = 1; slotid <= MAXSLOTS; slotid++) { + slot = &xhci->slots[slotid-1]; + if (slot->devaddr == dev->addr) { + return slotid; + } + } + return 0; +} + +static int xhci_find_epid(USBEndpoint *ep) +{ + if (ep->nr == 0) { + return 1; + } + if (ep->pid == USB_TOKEN_IN) { + return ep->nr * 2 + 1; + } else { + return ep->nr * 2; + } +} + +static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep) +{ + XHCIState *xhci = container_of(bus, XHCIState, bus); + int slotid; + + DPRINTF("%s\n", __func__); + slotid = xhci_find_slotid(xhci, ep->dev); + if (slotid == 0 || !xhci->slots[slotid-1].enabled) { + DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr); + return; + } + xhci_kick_ep(xhci, slotid, xhci_find_epid(ep)); +} + static USBBusOps xhci_bus_ops = { + .wakeup_endpoint = xhci_wakeup_endpoint, }; static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) @@ -2667,7 +2838,10 @@ static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) for (i = 0; i < MAXPORTS; i++) { memset(&xhci->ports[i], 0, sizeof(xhci->ports[i])); usb_register_port(&xhci->bus, &xhci->ports[i].port, xhci, i, - &xhci_port_ops, USB_SPEED_MASK_HIGH); + &xhci_port_ops, + USB_SPEED_MASK_LOW | + USB_SPEED_MASK_FULL | + USB_SPEED_MASK_HIGH); } for (i = 0; i < MAXSLOTS; i++) { xhci->slots[i].enabled = 0; @@ -2752,8 +2926,9 @@ static TypeInfo xhci_info = { .class_init = xhci_class_init, }; -static void xhci_register(void) +static void xhci_register_types(void) { type_register_static(&xhci_info); } -device_init(xhci_register); + +type_init(xhci_register_types) @@ -35,7 +35,8 @@ void usb_attach(USBPort *port) assert(dev->attached); assert(dev->state == USB_STATE_NOTATTACHED); port->ops->attach(port); - usb_send_msg(dev, USB_MSG_ATTACH); + dev->state = USB_STATE_ATTACHED; + usb_device_handle_attach(dev); } void usb_detach(USBPort *port) @@ -45,24 +46,41 @@ void usb_detach(USBPort *port) assert(dev != NULL); assert(dev->state != USB_STATE_NOTATTACHED); port->ops->detach(port); - usb_send_msg(dev, USB_MSG_DETACH); + dev->state = USB_STATE_NOTATTACHED; } -void usb_reset(USBPort *port) +void usb_port_reset(USBPort *port) { USBDevice *dev = port->dev; assert(dev != NULL); usb_detach(port); usb_attach(port); - usb_send_msg(dev, USB_MSG_RESET); + usb_device_reset(dev); } -void usb_wakeup(USBDevice *dev) +void usb_device_reset(USBDevice *dev) { + if (dev == NULL || !dev->attached) { + return; + } + dev->remote_wakeup = 0; + dev->addr = 0; + dev->state = USB_STATE_DEFAULT; + usb_device_handle_reset(dev); +} + +void usb_wakeup(USBEndpoint *ep) +{ + USBDevice *dev = ep->dev; + USBBus *bus = usb_bus_from_device(dev); + if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { dev->port->ops->wakeup(dev->port); } + if (bus->ops->wakeup_endpoint) { + bus->ops->wakeup_endpoint(bus, ep); + } } /**********************/ @@ -128,8 +146,7 @@ static int do_token_in(USBDevice *s, USBPacket *p) int request, value, index; int ret = 0; - if (p->devep != 0) - return usb_device_handle_data(s, p); + assert(p->ep->nr == 0); request = (s->setup_buf[0] << 8) | s->setup_buf[1]; value = (s->setup_buf[3] << 8) | s->setup_buf[2]; @@ -175,8 +192,7 @@ static int do_token_in(USBDevice *s, USBPacket *p) static int do_token_out(USBDevice *s, USBPacket *p) { - if (p->devep != 0) - return usb_device_handle_data(s, p); + assert(p->ep->nr == 0); switch(s->setup_state) { case SETUP_STATE_ACK: @@ -209,51 +225,6 @@ static int do_token_out(USBDevice *s, USBPacket *p) } } -/* - * Generic packet handler. - * Called by the HC (host controller). - * - * Returns length of the transaction or one of the USB_RET_XXX codes. - */ -int usb_generic_handle_packet(USBDevice *s, USBPacket *p) -{ - switch(p->pid) { - case USB_MSG_ATTACH: - s->state = USB_STATE_ATTACHED; - usb_device_handle_attach(s); - return 0; - - case USB_MSG_DETACH: - s->state = USB_STATE_NOTATTACHED; - return 0; - - case USB_MSG_RESET: - s->remote_wakeup = 0; - s->addr = 0; - s->state = USB_STATE_DEFAULT; - usb_device_handle_reset(s); - return 0; - } - - /* Rest of the PIDs must match our address */ - if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr) - return USB_RET_NODEV; - - switch (p->pid) { - case USB_TOKEN_SETUP: - return do_token_setup(s, p); - - case USB_TOKEN_IN: - return do_token_in(s, p); - - case USB_TOKEN_OUT: - return do_token_out(s, p); - - default: - return USB_RET_STALL; - } -} - /* ctrl complete function for devices which use usb_generic_handle_packet and may return USB_RET_ASYNC from their handle_control callback. Device code which does this *must* call this function instead of the normal @@ -301,17 +272,39 @@ int set_usb_string(uint8_t *buf, const char *str) return q - buf; } -/* Send an internal message to a USB device. */ -void usb_send_msg(USBDevice *dev, int msg) +USBDevice *usb_find_device(USBPort *port, uint8_t addr) { - USBPacket p; - int ret; + USBDevice *dev = port->dev; - memset(&p, 0, sizeof(p)); - p.pid = msg; - ret = usb_handle_packet(dev, &p); - /* This _must_ be synchronous */ - assert(ret != USB_RET_ASYNC); + if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) { + return NULL; + } + if (dev->addr == addr) { + return dev; + } + return usb_device_find_device(dev, addr); +} + +static int usb_process_one(USBPacket *p) +{ + USBDevice *dev = p->ep->dev; + + if (p->ep->nr == 0) { + /* control pipe */ + switch (p->pid) { + case USB_TOKEN_SETUP: + return do_token_setup(dev, p); + case USB_TOKEN_IN: + return do_token_in(dev, p); + case USB_TOKEN_OUT: + return do_token_out(dev, p); + default: + return USB_RET_STALL; + } + } else { + /* data pipe */ + return usb_device_handle_data(dev, p); + } } /* Hand over a packet to a device for processing. Return value @@ -321,17 +314,27 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p) { int ret; - assert(p->owner == NULL); - ret = usb_device_handle_packet(dev, p); - if (ret == USB_RET_ASYNC) { - if (p->owner == NULL) { - p->owner = usb_ep_get(dev, p->pid, p->devep); + if (dev == NULL) { + return USB_RET_NODEV; + } + assert(dev == p->ep->dev); + assert(dev->state == USB_STATE_DEFAULT); + assert(p->state == USB_PACKET_SETUP); + assert(p->ep != NULL); + + if (QTAILQ_EMPTY(&p->ep->queue)) { + ret = usb_process_one(p); + if (ret == USB_RET_ASYNC) { + usb_packet_set_state(p, USB_PACKET_ASYNC); + QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue); } else { - /* We'll end up here when usb_handle_packet is called - * recursively due to a hub being in the chain. Nothing - * to do. Leave p->owner pointing to the device, not the - * hub. */; + p->result = ret; + usb_packet_set_state(p, USB_PACKET_COMPLETE); } + } else { + ret = USB_RET_ASYNC; + usb_packet_set_state(p, USB_PACKET_QUEUED); + QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue); } return ret; } @@ -341,10 +344,28 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p) handle_packet. */ void usb_packet_complete(USBDevice *dev, USBPacket *p) { - /* Note: p->owner != dev is possible in case dev is a hub */ - assert(p->owner != NULL); - p->owner = NULL; + USBEndpoint *ep = p->ep; + int ret; + + assert(p->state == USB_PACKET_ASYNC); + assert(QTAILQ_FIRST(&ep->queue) == p); + usb_packet_set_state(p, USB_PACKET_COMPLETE); + QTAILQ_REMOVE(&ep->queue, p, queue); dev->port->ops->complete(dev->port, p); + + while (!QTAILQ_EMPTY(&ep->queue)) { + p = QTAILQ_FIRST(&ep->queue); + assert(p->state == USB_PACKET_QUEUED); + ret = usb_process_one(p); + if (ret == USB_RET_ASYNC) { + usb_packet_set_state(p, USB_PACKET_ASYNC); + break; + } + p->result = ret; + usb_packet_set_state(p, USB_PACKET_COMPLETE); + QTAILQ_REMOVE(&ep->queue, p, queue); + dev->port->ops->complete(dev->port, p); + } } /* Cancel an active packet. The packed must have been deferred by @@ -352,9 +373,13 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p) completed. */ void usb_cancel_packet(USBPacket * p) { - assert(p->owner != NULL); - usb_device_cancel_packet(p->owner->dev, p); - p->owner = NULL; + bool callback = (p->state == USB_PACKET_ASYNC); + assert(usb_packet_is_inflight(p)); + usb_packet_set_state(p, USB_PACKET_CANCELED); + QTAILQ_REMOVE(&p->ep->queue, p, queue); + if (callback) { + usb_device_cancel_packet(p->ep->dev, p); + } } @@ -363,13 +388,50 @@ void usb_packet_init(USBPacket *p) qemu_iovec_init(&p->iov, 1); } -void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep) +void usb_packet_set_state(USBPacket *p, USBPacketState state) +{ +#ifdef DEBUG + static const char *name[] = { + [USB_PACKET_UNDEFINED] = "undef", + [USB_PACKET_SETUP] = "setup", + [USB_PACKET_QUEUED] = "queued", + [USB_PACKET_ASYNC] = "async", + [USB_PACKET_COMPLETE] = "complete", + [USB_PACKET_CANCELED] = "canceled", + }; + static const char *rets[] = { + [-USB_RET_NODEV] = "NODEV", + [-USB_RET_NAK] = "NAK", + [-USB_RET_STALL] = "STALL", + [-USB_RET_BABBLE] = "BABBLE", + [-USB_RET_ASYNC] = "ASYNC", + }; + char add[16] = ""; + + if (state == USB_PACKET_COMPLETE) { + if (p->result < 0) { + snprintf(add, sizeof(add), " - %s", rets[-p->result]); + } else { + snprintf(add, sizeof(add), " - %d", p->result); + } + } + fprintf(stderr, "bus %s, port %s, dev %d, ep %d: packet %p: %s -> %s%s\n", + p->ep->dev->qdev.parent_bus->name, + p->ep->dev->port->path, + p->ep->dev->addr, p->ep->nr, + p, name[p->state], name[state], add); +#endif + p->state = state; +} + +void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep) { + assert(!usb_packet_is_inflight(p)); p->pid = pid; - p->devaddr = addr; - p->devep = ep; + p->ep = ep; p->result = 0; qemu_iovec_reset(&p->iov); + usb_packet_set_state(p, USB_PACKET_SETUP); } void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len) @@ -408,6 +470,7 @@ void usb_packet_skip(USBPacket *p, size_t bytes) void usb_packet_cleanup(USBPacket *p) { + assert(!usb_packet_is_inflight(p)); qemu_iovec_destroy(&p->iov); } @@ -415,16 +478,24 @@ void usb_ep_init(USBDevice *dev) { int ep; + dev->ep_ctl.nr = 0; dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; dev->ep_ctl.ifnum = 0; dev->ep_ctl.dev = dev; + QTAILQ_INIT(&dev->ep_ctl.queue); for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { + dev->ep_in[ep].nr = ep + 1; + dev->ep_out[ep].nr = ep + 1; + dev->ep_in[ep].pid = USB_TOKEN_IN; + dev->ep_out[ep].pid = USB_TOKEN_OUT; dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID; dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID; dev->ep_in[ep].ifnum = 0; dev->ep_out[ep].ifnum = 0; dev->ep_in[ep].dev = dev; dev->ep_out[ep].dev = dev; + QTAILQ_INIT(&dev->ep_in[ep].queue); + QTAILQ_INIT(&dev->ep_out[ep].queue); } } @@ -472,7 +543,12 @@ void usb_ep_dump(USBDevice *dev) struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep) { - struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out; + struct USBEndpoint *eps; + + if (dev == NULL) { + return NULL; + } + eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out; if (ep == 0) { return &dev->ep_ctl; } @@ -39,11 +39,6 @@ #define USB_TOKEN_IN 0x69 /* device -> host */ #define USB_TOKEN_OUT 0xe1 /* host -> device */ -/* specific usb messages, also sent in the 'pid' parameter */ -#define USB_MSG_ATTACH 0x100 -#define USB_MSG_DETACH 0x101 -#define USB_MSG_RESET 0x102 - #define USB_RET_NODEV (-1) #define USB_RET_NAK (-2) #define USB_RET_STALL (-3) @@ -176,10 +171,13 @@ struct USBDescString { #define USB_MAX_INTERFACES 16 struct USBEndpoint { + uint8_t nr; + uint8_t pid; uint8_t type; uint8_t ifnum; int max_packet_size; USBDevice *dev; + QTAILQ_HEAD(, USBPacket) queue; }; /* definition of a USB device */ @@ -234,13 +232,10 @@ typedef struct USBDeviceClass { int (*init)(USBDevice *dev); /* - * Process USB packet. - * Called by the HC (Host Controller). - * - * Returns length of the transaction - * or one of the USB_RET_XXX codes. + * Walk (enabled) downstream ports, check for a matching device. + * Only hubs implement this. */ - int (*handle_packet)(USBDevice *dev, USBPacket *p); + USBDevice *(*find_device)(USBDevice *dev, uint8_t addr); /* * Called when a packet is canceled. @@ -297,8 +292,7 @@ typedef struct USBPortOps { void (*wakeup)(USBPort *port); /* * Note that port->dev will be different then the device from which - * the packet originated when a hub is involved, if you want the orginating - * device use p->owner + * the packet originated when a hub is involved. */ void (*complete)(USBPort *port, USBPacket *p); } USBPortOps; @@ -316,20 +310,30 @@ struct USBPort { typedef void USBCallback(USBPacket * packet, void *opaque); +typedef enum USBPacketState { + USB_PACKET_UNDEFINED = 0, + USB_PACKET_SETUP, + USB_PACKET_QUEUED, + USB_PACKET_ASYNC, + USB_PACKET_COMPLETE, + USB_PACKET_CANCELED, +} USBPacketState; + /* Structure used to hold information about an active USB packet. */ struct USBPacket { /* Data fields for use by the driver. */ int pid; - uint8_t devaddr; - uint8_t devep; + USBEndpoint *ep; QEMUIOVector iov; int result; /* transfer length or USB_RET_* status code */ /* Internal use by the USB layer. */ - USBEndpoint *owner; + USBPacketState state; + QTAILQ_ENTRY(USBPacket) queue; }; void usb_packet_init(USBPacket *p); -void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep); +void usb_packet_set_state(USBPacket *p, USBPacketState state); +void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep); void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len); int usb_packet_map(USBPacket *p, QEMUSGList *sgl); void usb_packet_unmap(USBPacket *p); @@ -337,6 +341,14 @@ void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes); void usb_packet_skip(USBPacket *p, size_t bytes); void usb_packet_cleanup(USBPacket *p); +static inline bool usb_packet_is_inflight(USBPacket *p) +{ + return (p->state == USB_PACKET_QUEUED || + p->state == USB_PACKET_ASYNC); +} + +USBDevice *usb_find_device(USBPort *port, uint8_t addr); + int usb_handle_packet(USBDevice *dev, USBPacket *p); void usb_packet_complete(USBDevice *dev, USBPacket *p); void usb_cancel_packet(USBPacket * p); @@ -354,12 +366,11 @@ int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep); void usb_attach(USBPort *port); void usb_detach(USBPort *port); -void usb_reset(USBPort *port); -void usb_wakeup(USBDevice *dev); -int usb_generic_handle_packet(USBDevice *s, USBPacket *p); +void usb_port_reset(USBPort *port); +void usb_device_reset(USBDevice *dev); +void usb_wakeup(USBEndpoint *ep); void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p); int set_usb_string(uint8_t *buf, const char *str); -void usb_send_msg(USBDevice *dev, int msg); /* usb-linux.c */ USBDevice *usb_host_device_open(const char *devname); @@ -414,6 +425,7 @@ struct USBBus { struct USBBusOps { int (*register_companion)(USBBus *bus, USBPort *ports[], uint32_t portcount, uint32_t firstport); + void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep); }; void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); @@ -451,7 +463,7 @@ extern const VMStateDescription vmstate_usb_device; .offset = vmstate_offset_value(_state, _field, USBDevice), \ } -int usb_device_handle_packet(USBDevice *dev, USBPacket *p); +USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr); void usb_device_cancel_packet(USBDevice *dev, USBPacket *p); diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index c4105e9..ae53a8b 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -154,11 +154,11 @@ static TypeInfo pci_realview_info = { .class_init = pci_realview_class_init, }; -static void versatile_pci_register_devices(void) +static void versatile_pci_register_types(void) { type_register_static(&pci_vpb_info); type_register_static(&pci_realview_info); type_register_static(&versatile_pci_host_info); } -device_init(versatile_pci_register_devices) +type_init(versatile_pci_register_types) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 6e28e78..1903db6 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -198,8 +198,8 @@ static void versatile_init(ram_addr_t ram_size, sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004); - qdev_init_nofail(sysctl); qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000); + qdev_init_nofail(sysctl); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); cpu_pic = arm_pic_init_cpu(env); @@ -382,9 +382,9 @@ static TypeInfo vpb_sic_info = { .class_init = vpb_sic_class_init, }; -static void versatilepb_register_devices(void) +static void versatilepb_register_types(void) { type_register_static(&vpb_sic_info); } -device_init(versatilepb_register_devices) +type_init(versatilepb_register_types) diff --git a/hw/vexpress.c b/hw/vexpress.c index 64fab45..43f47a6 100644 --- a/hw/vexpress.c +++ b/hw/vexpress.c @@ -123,8 +123,8 @@ static void vexpress_a9_init(ram_addr_t ram_size, /* 0x10000000 System registers */ sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); - qdev_init_nofail(sysctl); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); + qdev_init_nofail(sysctl); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); /* 0x10001000 SP810 system control */ diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 8d3ff0d..4bcc4db 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -85,8 +85,9 @@ static TypeInfo vga_info = { .class_init = vga_class_initfn, }; -static void vga_register(void) +static void vga_register_types(void) { type_register_static(&vga_info); } -device_init(vga_register) + +type_init(vga_register_types) diff --git a/hw/vga-pci.c b/hw/vga-pci.c index 974a7a9..465b643 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -96,8 +96,9 @@ static TypeInfo vga_info = { .class_init = vga_class_init, }; -static void vga_register(void) +static void vga_register_types(void) { type_register_static(&vga_info); } -device_init(vga_register); + +type_init(vga_register_types) @@ -1777,10 +1777,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (!(s->cr[VGA_CRTC_MODE] & 2)) { addr = (addr & ~0x8000) | ((y1 & 2) << 14); } + update = full_update; page0 = addr; page1 = addr + bwidth - 1; - update = memory_region_get_dirty(&s->vram, page0, page1, - DIRTY_MEMORY_VGA); + update |= memory_region_get_dirty(&s->vram, page0, page1 - page0, + DIRTY_MEMORY_VGA); /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; if (update) { diff --git a/hw/virtio-console.c b/hw/virtio-console.c index 4f2c3e4..cffee3d 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -149,12 +149,6 @@ static TypeInfo virtconsole_info = { .class_init = virtconsole_class_init, }; -static void virtconsole_register(void) -{ - type_register_static(&virtconsole_info); -} -device_init(virtconsole_register) - static Property virtserialport_properties[] = { DEFINE_PROP_CHR("chardev", VirtConsole, chr), DEFINE_PROP_END_OF_LIST(), @@ -179,8 +173,10 @@ static TypeInfo virtserialport_info = { .class_init = virtserialport_class_init, }; -static void virtserialport_register(void) +static void virtconsole_register_types(void) { + type_register_static(&virtconsole_info); type_register_static(&virtserialport_info); } -device_init(virtserialport_register) + +type_init(virtconsole_register_types) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 93fff54..907b52a 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -930,7 +930,7 @@ static TypeInfo virtio_balloon_info = { .class_init = virtio_balloon_class_init, }; -static void virtio_pci_register_devices(void) +static void virtio_pci_register_types(void) { type_register_static(&virtio_blk_info); type_register_static(&virtio_net_info); @@ -938,4 +938,4 @@ static void virtio_pci_register_devices(void) type_register_static(&virtio_balloon_info); } -device_init(virtio_pci_register_devices) +type_init(virtio_pci_register_types) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 6117629..e22940e 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -949,9 +949,9 @@ static TypeInfo virtio_serial_port_type_info = { .class_init = virtio_serial_port_class_init, }; -static void virtio_serial_register_devices(void) +static void virtio_serial_register_types(void) { type_register_static(&virtio_serial_port_type_info); } -device_init(virtio_serial_register_devices); +type_init(virtio_serial_register_types) diff --git a/hw/vmmouse.c b/hw/vmmouse.c index fda4f89..6338efa 100644 --- a/hw/vmmouse.c +++ b/hw/vmmouse.c @@ -294,8 +294,9 @@ static TypeInfo vmmouse_info = { .class_init = vmmouse_class_initfn, }; -static void vmmouse_dev_register(void) +static void vmmouse_register_types(void) { type_register_static(&vmmouse_info); } -device_init(vmmouse_dev_register) + +type_init(vmmouse_register_types) diff --git a/hw/vmport.c b/hw/vmport.c index a2c45e1..9373be9 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -159,8 +159,9 @@ static TypeInfo vmport_info = { .class_init = vmport_class_initfn, }; -static void vmport_dev_register(void) +static void vmport_register_types(void) { type_register_static(&vmport_info); } -device_init(vmport_dev_register) + +type_init(vmport_register_types) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 3f3eb21..f8afa3c 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1223,8 +1223,9 @@ static TypeInfo vmsvga_info = { .class_init = vmsvga_class_init, }; -static void vmsvga_register(void) +static void vmsvga_register_types(void) { type_register_static(&vmsvga_info); } -device_init(vmsvga_register); + +type_init(vmsvga_register_types) diff --git a/hw/vt82c686.c b/hw/vt82c686.c index aa0954f..fbab0bb 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -366,13 +366,6 @@ static TypeInfo via_ac97_info = { .class_init = via_ac97_class_init, }; -static void vt82c686b_ac97_register(void) -{ - type_register_static(&via_ac97_info); -} - -device_init(vt82c686b_ac97_register); - static int vt82c686b_mc97_initfn(PCIDevice *dev) { VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev); @@ -414,13 +407,6 @@ static TypeInfo via_mc97_info = { .class_init = via_mc97_class_init, }; -static void vt82c686b_mc97_register(void) -{ - type_register_static(&via_mc97_info); -} - -device_init(vt82c686b_mc97_register); - /* vt82c686 pm init */ static int vt82c686b_pm_initfn(PCIDevice *dev) { @@ -497,13 +483,6 @@ static TypeInfo via_pm_info = { .class_init = via_pm_class_init, }; -static void vt82c686b_pm_register(void) -{ - type_register_static(&via_pm_info); -} - -device_init(vt82c686b_pm_register); - static const VMStateDescription vmstate_via = { .name = "vt82c686b", .version_id = 1, @@ -571,8 +550,12 @@ static TypeInfo via_info = { .class_init = via_class_init, }; -static void vt82c686b_register(void) +static void vt82c686b_register_types(void) { + type_register_static(&via_ac97_info); + type_register_static(&via_mc97_info); + type_register_static(&via_pm_info); type_register_static(&via_info); } -device_init(vt82c686b_register); + +type_init(vt82c686b_register_types) diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index 41325f0..15c69db 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -448,10 +448,10 @@ static TypeInfo i6300esb_info = { .class_init = i6300esb_class_init, }; -static void i6300esb_register_devices(void) +static void i6300esb_register_types(void) { watchdog_add_model(&model); type_register_static(&i6300esb_info); } -device_init(i6300esb_register_devices); +type_init(i6300esb_register_types) diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c index 8faa231..7f6c21d 100644 --- a/hw/wdt_ib700.c +++ b/hw/wdt_ib700.c @@ -136,10 +136,10 @@ static TypeInfo wdt_ib700_info = { .class_init = wdt_ib700_class_init, }; -static void wdt_ib700_register_devices(void) +static void wdt_ib700_register_types(void) { watchdog_add_model(&model); type_register_static(&wdt_ib700_info); } -device_init(wdt_ib700_register_devices); +type_init(wdt_ib700_register_types) diff --git a/hw/wm8750.c b/hw/wm8750.c index 18afa4c..11bcec3 100644 --- a/hw/wm8750.c +++ b/hw/wm8750.c @@ -708,9 +708,9 @@ static TypeInfo wm8750_info = { .class_init = wm8750_class_init, }; -static void wm8750_register_devices(void) +static void wm8750_register_types(void) { type_register_static(&wm8750_info); } -device_init(wm8750_register_devices) +type_init(wm8750_register_types) diff --git a/hw/xen_platform.c b/hw/xen_platform.c index e757102..5a7c4cc 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -396,9 +396,9 @@ static TypeInfo xen_platform_info = { .class_init = xen_platform_class_init, }; -static void xen_platform_register(void) +static void xen_platform_register_types(void) { type_register_static(&xen_platform_info); } -device_init(xen_platform_register); +type_init(xen_platform_register_types) @@ -425,9 +425,9 @@ static TypeInfo xgmac_enet_info = { .class_init = xgmac_enet_class_init, }; -static void xgmac_enet_register(void) +static void xgmac_enet_register_types(void) { type_register_static(&xgmac_enet_info); } -device_init(xgmac_enet_register) +type_init(xgmac_enet_register_types) diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c index e8a5312..85dfcbf 100644 --- a/hw/xilinx_axidma.c +++ b/hw/xilinx_axidma.c @@ -508,9 +508,9 @@ static TypeInfo axidma_info = { .class_init = axidma_class_init, }; -static void xilinx_axidma_register(void) +static void xilinx_axidma_register_types(void) { type_register_static(&axidma_info); } -device_init(xilinx_axidma_register) +type_init(xilinx_axidma_register_types) diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c index 1ce2db4..7526273 100644 --- a/hw/xilinx_axienet.c +++ b/hw/xilinx_axienet.c @@ -894,9 +894,10 @@ static TypeInfo xilinx_enet_info = { .instance_size = sizeof(struct XilinxAXIEnet), .class_init = xilinx_enet_class_init, }; -static void xilinx_enet_register(void) + +static void xilinx_enet_register_types(void) { type_register_static(&xilinx_enet_info); } -device_init(xilinx_enet_register) +type_init(xilinx_enet_register_types) diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c index 499feef..857b33d 100644 --- a/hw/xilinx_ethlite.c +++ b/hw/xilinx_ethlite.c @@ -249,9 +249,9 @@ static TypeInfo xilinx_ethlite_info = { .class_init = xilinx_ethlite_class_init, }; -static void xilinx_ethlite_register(void) +static void xilinx_ethlite_register_types(void) { type_register_static(&xilinx_ethlite_info); } -device_init(xilinx_ethlite_register) +type_init(xilinx_ethlite_register_types) diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c index 73eed6d..553f848 100644 --- a/hw/xilinx_intc.c +++ b/hw/xilinx_intc.c @@ -182,9 +182,9 @@ static TypeInfo xilinx_intc_info = { .class_init = xilinx_intc_class_init, }; -static void xilinx_intc_register(void) +static void xilinx_intc_register_types(void) { type_register_static(&xilinx_intc_info); } -device_init(xilinx_intc_register) +type_init(xilinx_intc_register_types) diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c index c8236d2..3ab2f2b 100644 --- a/hw/xilinx_timer.c +++ b/hw/xilinx_timer.c @@ -241,9 +241,9 @@ static TypeInfo xilinx_timer_info = { .class_init = xilinx_timer_class_init, }; -static void xilinx_timer_register(void) +static void xilinx_timer_register_types(void) { type_register_static(&xilinx_timer_info); } -device_init(xilinx_timer_register) +type_init(xilinx_timer_register_types) diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c index 1c2b908..aa0170d 100644 --- a/hw/xilinx_uartlite.c +++ b/hw/xilinx_uartlite.c @@ -225,9 +225,9 @@ static TypeInfo xilinx_uartlite_info = { .class_init = xilinx_uartlite_class_init, }; -static void xilinx_uart_register(void) +static void xilinx_uart_register_types(void) { type_register_static(&xilinx_uartlite_info); } -device_init(xilinx_uart_register) +type_init(xilinx_uart_register_types) diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c index 07e4fc1..319624f 100644 --- a/hw/xio3130_downstream.c +++ b/hw/xio3130_downstream.c @@ -203,12 +203,12 @@ static TypeInfo xio3130_downstream_info = { .class_init = xio3130_downstream_class_init, }; -static void xio3130_downstream_register(void) +static void xio3130_downstream_register_types(void) { type_register_static(&xio3130_downstream_info); } -device_init(xio3130_downstream_register); +type_init(xio3130_downstream_register_types) /* * Local variables: diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c index 7887c92..34a99bb 100644 --- a/hw/xio3130_upstream.c +++ b/hw/xio3130_upstream.c @@ -177,12 +177,12 @@ static TypeInfo xio3130_upstream_info = { .class_init = xio3130_upstream_class_init, }; -static void xio3130_upstream_register(void) +static void xio3130_upstream_register_types(void) { type_register_static(&xio3130_upstream_info); } -device_init(xio3130_upstream_register); +type_init(xio3130_upstream_register_types) /* diff --git a/hw/zaurus.c b/hw/zaurus.c index 055df9b..72838ec 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -243,11 +243,12 @@ static TypeInfo scoop_sysbus_info = { .class_init = scoop_sysbus_class_init, }; -static void scoop_register(void) +static void scoop_register_types(void) { type_register_static(&scoop_sysbus_info); } -device_init(scoop_register); + +type_init(scoop_register_types) /* Write the bootloader parameters memory area. */ |