On Monday 24 September 2007, Rusty Russell wrote:
> This attempts to implement a "virtual I/O" layer which should allow
> common drivers to be efficiently used across most virtual I/O
> mechanisms.  It will no-doubt need further enhancement.

Hi Rusty,

Thanks for your update, as you can imagine, I'm much happier with
this version ;-)

> +
> +struct virtio_bus {
> +     struct bus_type bus;
> +     struct device dev;
> +};
> +
> +static struct virtio_bus virtio_bus = {
> +     .bus = {
> +             .name  = "virtio",
> +             .match = virtio_dev_match,
> +             .dev_attrs = virtio_dev_attrs,
> +     },
> +     .dev = {
> +             /* Can override this if you have a real bus behind it. */
> +             .parent = NULL,
> +             .bus_id = "virtio",
> +     }
> +};

This is a pattern I've seen a few times before, but could never understand
what it's good for. What is your reason for defining a new data structure
that is used only once, instead of just

static struct bus_type virtio_bus_type;
static struct device virtio_root_dev;

Also, I would not mix the two in a single source file. Instead, I think
every driver that can provide virtio devices (pci, lguest, ...) should
be responsible for setting the parent appropriately.

> +#ifndef _LINUX_VIRTIO_CONFIG_H
> +#define _LINUX_VIRTIO_CONFIG_H
> +/* Virtio devices use a standardized configuration space to define their
> + * features and pass configuration information, but each implementation can
> + * store and access that space differently. */
> +#include <linux/types.h>
> +
> +/* Status byte for guest to report progress, and synchronize config. */
> +/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) 
> */
> +#define VIRTIO_CONFIG_S_ACKNOWLEDGE  1
> +/* We have found a driver for the device. */
> +#define VIRTIO_CONFIG_S_DRIVER               2
> +/* Driver has used its parts of the config, and is happy */
> +#define VIRTIO_CONFIG_S_DRIVER_OK    4
> +/* We've given up on this device. */
> +#define VIRTIO_CONFIG_S_FAILED               0x80
> +
> +/* Feature byte (actually 7 bits availabe): */
> +/* Requirements/features of the virtio implementation. */
> +#define VIRTIO_CONFIG_F_VIRTIO 1
> +/* Requirements/features of the virtqueue (may have more than one). */
> +#define VIRTIO_CONFIG_F_VIRTQUEUE 2
> +
> +#ifdef __KERNEL__
> +struct virtio_device;
> +
> +/**
> + * virtio_config_ops - operations for configuring a virtio device
> + * @find: search for the next configuration field of the given type.
> + *   vdev: the virtio_device
> + *   type: the feature type
> + *   len: the (returned) length of the field if found.
> + *   Returns a token if found, or NULL.  Never returnes the same field twice
> + *   (ie. it's used up).
> + * @get: read the value of a configuration field after find().
> + *   vdev: the virtio_device
> + *   token: the token returned from find().
> + *   buf: the buffer to write the field value into.
> + *   len: the length of the buffer (given by find()).
> + *   Note that contents are conventionally little-endian.
> + * @set: write the value of a configuration field after find().
> + *   vdev: the virtio_device
> + *   token: the token returned from find().
> + *   buf: the buffer to read the field value from.
> + *   len: the length of the buffer (given by find()).
> + *   Note that contents are conventionally little-endian.
> + * @get_status: read the status byte
> + *   vdev: the virtio_device
> + *   Returns the status byte
> + * @set_status: write the status byte
> + *   vdev: the virtio_device
> + *   status: the new status byte
> + * @find_vq: find the first VIRTIO_CONFIG_F_VIRTQUEUE and create a virtqueue.
> + *   vdev: the virtio_device
> + *   callback: the virqtueue callback
> + *   Returns the new virtqueue or ERR_PTR().
> + * @del_vq: free a virtqueue found by find_vq().
> + */
> +struct virtio_config_ops
> +{
> +     void *(*find)(struct virtio_device *vdev, u8 type, unsigned *len);
> +     void (*get)(struct virtio_device *vdev, void *token,
> +                 void *buf, unsigned len);
> +     void (*set)(struct virtio_device *vdev, void *token,
> +                 const void *buf, unsigned len);
> +     u8 (*get_status)(struct virtio_device *vdev);
> +     void (*set_status)(struct virtio_device *vdev, u8 status);
> +     struct virtqueue *(*find_vq)(struct virtio_device *vdev,
> +                                  bool (*callback)(struct virtqueue *));
> +     void (*del_vq)(struct virtqueue *vq);
> +};

The configuration logic looks more complicated than it should be.
Maybe more of this can be done using data structure definitions instead
of dynamic callback. E.g. the virtqueues of a given device can be
listed as members of the struct virtio_device.

> +/**
> + * virtio_config_val - get a single virtio config and mark it used.
> + * @config: the virtio config space
> + * @type: the type to search for.
> + * @val: a pointer to the value to fill in.
> + *
> + * Once used, the config type is marked with VIRTIO_CONFIG_F_USED so it can't
> + * be found again.  This version does endian conversion. */
> +#define virtio_config_val(vdev, type, v) ({                          \
> +     int _err = __virtio_config_val((vdev),(type),(v),sizeof(*(v))); \
> +                                                                     \
> +     BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2             \
> +                  && sizeof(*(v)) != 4 && sizeof(*(v)) != 8);        \
> +     if (!_err) {                                                    \
> +             switch (sizeof(*(v))) {                                 \
> +             case 2: le16_to_cpus(v); break;                         \
> +             case 4: le32_to_cpus(v); break;                         \
> +             case 8: le64_to_cpus(v); break;                         \
> +             }                                                       \
> +     }                                                               \
> +     _err;                                                           \
> +})

Especially the macro looks like something better avoided...

        Arnd <><

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to