linux/include/linux/virtio_config.h
<<
>>
Prefs
   1#ifndef _LINUX_VIRTIO_CONFIG_H
   2#define _LINUX_VIRTIO_CONFIG_H
   3
   4#include <linux/err.h>
   5#include <linux/bug.h>
   6#include <linux/virtio.h>
   7#include <linux/virtio_byteorder.h>
   8#include <uapi/linux/virtio_config.h>
   9
  10/**
  11 * virtio_config_ops - operations for configuring a virtio device
  12 * @get: read the value of a configuration field
  13 *      vdev: the virtio_device
  14 *      offset: the offset of the configuration field
  15 *      buf: the buffer to write the field value into.
  16 *      len: the length of the buffer
  17 * @set: write the value of a configuration field
  18 *      vdev: the virtio_device
  19 *      offset: the offset of the configuration field
  20 *      buf: the buffer to read the field value from.
  21 *      len: the length of the buffer
  22 * @generation: config generation counter
  23 *      vdev: the virtio_device
  24 *      Returns the config generation counter
  25 * @get_status: read the status byte
  26 *      vdev: the virtio_device
  27 *      Returns the status byte
  28 * @set_status: write the status byte
  29 *      vdev: the virtio_device
  30 *      status: the new status byte
  31 * @reset: reset the device
  32 *      vdev: the virtio device
  33 *      After this, status and feature negotiation must be done again
  34 *      Device must not be reset from its vq/config callbacks, or in
  35 *      parallel with being added/removed.
  36 * @find_vqs: find virtqueues and instantiate them.
  37 *      vdev: the virtio_device
  38 *      nvqs: the number of virtqueues to find
  39 *      vqs: on success, includes new virtqueues
  40 *      callbacks: array of callbacks, for each virtqueue
  41 *              include a NULL entry for vqs that do not need a callback
  42 *      names: array of virtqueue names (mainly for debugging)
  43 *              include a NULL entry for vqs unused by driver
  44 *      Returns 0 on success or error status
  45 * @del_vqs: free virtqueues found by find_vqs().
  46 * @get_features: get the array of feature bits for this device.
  47 *      vdev: the virtio_device
  48 *      Returns the first 32 feature bits (all we currently need).
  49 * @finalize_features: confirm what device features we'll be using.
  50 *      vdev: the virtio_device
  51 *      This gives the final feature bits for the device: it can change
  52 *      the dev->feature bits if it wants.
  53 *      Returns 0 on success or error status
  54 * @bus_name: return the bus name associated with the device
  55 *      vdev: the virtio_device
  56 *      This returns a pointer to the bus name a la pci_name from which
  57 *      the caller can then copy.
  58 * @set_vq_affinity: set the affinity for a virtqueue.
  59 */
  60typedef void vq_callback_t(struct virtqueue *);
  61struct virtio_config_ops {
  62        void (*get)(struct virtio_device *vdev, unsigned offset,
  63                    void *buf, unsigned len);
  64        void (*set)(struct virtio_device *vdev, unsigned offset,
  65                    const void *buf, unsigned len);
  66        u32 (*generation)(struct virtio_device *vdev);
  67        u8 (*get_status)(struct virtio_device *vdev);
  68        void (*set_status)(struct virtio_device *vdev, u8 status);
  69        void (*reset)(struct virtio_device *vdev);
  70        int (*find_vqs)(struct virtio_device *, unsigned nvqs,
  71                        struct virtqueue *vqs[],
  72                        vq_callback_t *callbacks[],
  73                        const char * const names[]);
  74        void (*del_vqs)(struct virtio_device *);
  75        u64 (*get_features)(struct virtio_device *vdev);
  76        int (*finalize_features)(struct virtio_device *vdev);
  77        const char *(*bus_name)(struct virtio_device *vdev);
  78        int (*set_vq_affinity)(struct virtqueue *vq, int cpu);
  79};
  80
  81/* If driver didn't advertise the feature, it will never appear. */
  82void virtio_check_driver_offered_feature(const struct virtio_device *vdev,
  83                                         unsigned int fbit);
  84
  85/**
  86 * __virtio_test_bit - helper to test feature bits. For use by transports.
  87 *                     Devices should normally use virtio_has_feature,
  88 *                     which includes more checks.
  89 * @vdev: the device
  90 * @fbit: the feature bit
  91 */
  92static inline bool __virtio_test_bit(const struct virtio_device *vdev,
  93                                     unsigned int fbit)
  94{
  95        /* Did you forget to fix assumptions on max features? */
  96        if (__builtin_constant_p(fbit))
  97                BUILD_BUG_ON(fbit >= 64);
  98        else
  99                BUG_ON(fbit >= 64);
 100
 101        return vdev->features & BIT_ULL(fbit);
 102}
 103
 104/**
 105 * __virtio_set_bit - helper to set feature bits. For use by transports.
 106 * @vdev: the device
 107 * @fbit: the feature bit
 108 */
 109static inline void __virtio_set_bit(struct virtio_device *vdev,
 110                                    unsigned int fbit)
 111{
 112        /* Did you forget to fix assumptions on max features? */
 113        if (__builtin_constant_p(fbit))
 114                BUILD_BUG_ON(fbit >= 64);
 115        else
 116                BUG_ON(fbit >= 64);
 117
 118        vdev->features |= BIT_ULL(fbit);
 119}
 120
 121/**
 122 * __virtio_clear_bit - helper to clear feature bits. For use by transports.
 123 * @vdev: the device
 124 * @fbit: the feature bit
 125 */
 126static inline void __virtio_clear_bit(struct virtio_device *vdev,
 127                                      unsigned int fbit)
 128{
 129        /* Did you forget to fix assumptions on max features? */
 130        if (__builtin_constant_p(fbit))
 131                BUILD_BUG_ON(fbit >= 64);
 132        else
 133                BUG_ON(fbit >= 64);
 134
 135        vdev->features &= ~BIT_ULL(fbit);
 136}
 137
 138/**
 139 * virtio_has_feature - helper to determine if this device has this feature.
 140 * @vdev: the device
 141 * @fbit: the feature bit
 142 */
 143static inline bool virtio_has_feature(const struct virtio_device *vdev,
 144                                      unsigned int fbit)
 145{
 146        if (fbit < VIRTIO_TRANSPORT_F_START)
 147                virtio_check_driver_offered_feature(vdev, fbit);
 148
 149        return __virtio_test_bit(vdev, fbit);
 150}
 151
 152/**
 153 * virtio_config_val - look for a feature and get a virtio config entry.
 154 * @vdev: the virtio device
 155 * @fbit: the feature bit
 156 * @offset: the type to search for.
 157 * @v: a pointer to the value to fill in.
 158 *
 159 * The return value is -ENOENT if the feature doesn't exist.  Otherwise
 160 * the config value is copied into whatever is pointed to by v. */
 161#define virtio_config_val(vdev, fbit, offset, v) \
 162        virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(*v))
 163
 164#define virtio_config_val_len(vdev, fbit, offset, v, len) \
 165        virtio_config_buf((vdev), (fbit), (offset), (v), (len))
 166
 167static inline int virtio_config_buf(struct virtio_device *vdev,
 168                                    unsigned int fbit,
 169                                    unsigned int offset,
 170                                    void *buf, unsigned len)
 171{
 172        if (!virtio_has_feature(vdev, fbit))
 173                return -ENOENT;
 174
 175        vdev->config->get(vdev, offset, buf, len);
 176        return 0;
 177}
 178
 179/**
 180 * virtio_has_iommu_quirk - determine whether this device has the iommu quirk
 181 * @vdev: the device
 182 */
 183static inline bool virtio_has_iommu_quirk(const struct virtio_device *vdev)
 184{
 185        /*
 186         * Note the reverse polarity of the quirk feature (compared to most
 187         * other features), this is for compatibility with legacy systems.
 188         */
 189        return !virtio_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
 190}
 191
 192static inline
 193struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
 194                                        vq_callback_t *c, const char *n)
 195{
 196        vq_callback_t *callbacks[] = { c };
 197        const char *names[] = { n };
 198        struct virtqueue *vq;
 199        int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names);
 200        if (err < 0)
 201                return ERR_PTR(err);
 202        return vq;
 203}
 204
 205/**
 206 * virtio_device_ready - enable vq use in probe function
 207 * @vdev: the device
 208 *
 209 * Driver must call this to use vqs in the probe function.
 210 *
 211 * Note: vqs are enabled automatically after probe returns.
 212 */
 213static inline
 214void virtio_device_ready(struct virtio_device *dev)
 215{
 216        unsigned status = dev->config->get_status(dev);
 217
 218        BUG_ON(status & VIRTIO_CONFIG_S_DRIVER_OK);
 219        dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK);
 220}
 221
 222static inline
 223const char *virtio_bus_name(struct virtio_device *vdev)
 224{
 225        if (!vdev->config->bus_name)
 226                return "virtio";
 227        return vdev->config->bus_name(vdev);
 228}
 229
 230/**
 231 * virtqueue_set_affinity - setting affinity for a virtqueue
 232 * @vq: the virtqueue
 233 * @cpu: the cpu no.
 234 *
 235 * Pay attention the function are best-effort: the affinity hint may not be set
 236 * due to config support, irq type and sharing.
 237 *
 238 */
 239static inline
 240int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
 241{
 242        struct virtio_device *vdev = vq->vdev;
 243        if (vdev->config->set_vq_affinity)
 244                return vdev->config->set_vq_affinity(vq, cpu);
 245        return 0;
 246}
 247
 248static inline bool virtio_is_little_endian(struct virtio_device *vdev)
 249{
 250        return virtio_has_feature(vdev, VIRTIO_F_VERSION_1) ||
 251                virtio_legacy_is_little_endian();
 252}
 253
 254/* Memory accessors */
 255static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
 256{
 257        return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
 258}
 259
 260static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
 261{
 262        return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
 263}
 264
 265static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
 266{
 267        return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
 268}
 269
 270static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
 271{
 272        return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
 273}
 274
 275static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
 276{
 277        return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
 278}
 279
 280static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
 281{
 282        return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
 283}
 284
 285/* Config space accessors. */
 286#define virtio_cread(vdev, structname, member, ptr)                     \
 287        do {                                                            \
 288                /* Must match the member's type, and be integer */      \
 289                if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
 290                        (*ptr) = 1;                                     \
 291                                                                        \
 292                switch (sizeof(*ptr)) {                                 \
 293                case 1:                                                 \
 294                        *(ptr) = virtio_cread8(vdev,                    \
 295                                               offsetof(structname, member)); \
 296                        break;                                          \
 297                case 2:                                                 \
 298                        *(ptr) = virtio_cread16(vdev,                   \
 299                                                offsetof(structname, member)); \
 300                        break;                                          \
 301                case 4:                                                 \
 302                        *(ptr) = virtio_cread32(vdev,                   \
 303                                                offsetof(structname, member)); \
 304                        break;                                          \
 305                case 8:                                                 \
 306                        *(ptr) = virtio_cread64(vdev,                   \
 307                                                offsetof(structname, member)); \
 308                        break;                                          \
 309                default:                                                \
 310                        BUG();                                          \
 311                }                                                       \
 312        } while(0)
 313
 314/* Config space accessors. */
 315#define virtio_cwrite(vdev, structname, member, ptr)                    \
 316        do {                                                            \
 317                /* Must match the member's type, and be integer */      \
 318                if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \
 319                        BUG_ON((*ptr) == 1);                            \
 320                                                                        \
 321                switch (sizeof(*ptr)) {                                 \
 322                case 1:                                                 \
 323                        virtio_cwrite8(vdev,                            \
 324                                       offsetof(structname, member),    \
 325                                       *(ptr));                         \
 326                        break;                                          \
 327                case 2:                                                 \
 328                        virtio_cwrite16(vdev,                           \
 329                                        offsetof(structname, member),   \
 330                                        *(ptr));                        \
 331                        break;                                          \
 332                case 4:                                                 \
 333                        virtio_cwrite32(vdev,                           \
 334                                        offsetof(structname, member),   \
 335                                        *(ptr));                        \
 336                        break;                                          \
 337                case 8:                                                 \
 338                        virtio_cwrite64(vdev,                           \
 339                                        offsetof(structname, member),   \
 340                                        *(ptr));                        \
 341                        break;                                          \
 342                default:                                                \
 343                        BUG();                                          \
 344                }                                                       \
 345        } while(0)
 346
 347/* Read @count fields, @bytes each. */
 348static inline void __virtio_cread_many(struct virtio_device *vdev,
 349                                       unsigned int offset,
 350                                       void *buf, size_t count, size_t bytes)
 351{
 352        u32 old, gen = vdev->config->generation ?
 353                vdev->config->generation(vdev) : 0;
 354        int i;
 355
 356        do {
 357                old = gen;
 358
 359                for (i = 0; i < count; i++)
 360                        vdev->config->get(vdev, offset + bytes * i,
 361                                          buf + i * bytes, bytes);
 362
 363                gen = vdev->config->generation ?
 364                        vdev->config->generation(vdev) : 0;
 365        } while (gen != old);
 366}
 367
 368static inline void virtio_cread_bytes(struct virtio_device *vdev,
 369                                      unsigned int offset,
 370                                      void *buf, size_t len)
 371{
 372        __virtio_cread_many(vdev, offset, buf, len, 1);
 373}
 374
 375static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset)
 376{
 377        u8 ret;
 378        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 379        return ret;
 380}
 381
 382static inline void virtio_cwrite8(struct virtio_device *vdev,
 383                                  unsigned int offset, u8 val)
 384{
 385        vdev->config->set(vdev, offset, &val, sizeof(val));
 386}
 387
 388static inline u16 virtio_cread16(struct virtio_device *vdev,
 389                                 unsigned int offset)
 390{
 391        u16 ret;
 392        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 393        return virtio16_to_cpu(vdev, (__force __virtio16)ret);
 394}
 395
 396static inline void virtio_cwrite16(struct virtio_device *vdev,
 397                                   unsigned int offset, u16 val)
 398{
 399        val = (__force u16)cpu_to_virtio16(vdev, val);
 400        vdev->config->set(vdev, offset, &val, sizeof(val));
 401}
 402
 403static inline u32 virtio_cread32(struct virtio_device *vdev,
 404                                 unsigned int offset)
 405{
 406        u32 ret;
 407        vdev->config->get(vdev, offset, &ret, sizeof(ret));
 408        return virtio32_to_cpu(vdev, (__force __virtio32)ret);
 409}
 410
 411static inline void virtio_cwrite32(struct virtio_device *vdev,
 412                                   unsigned int offset, u32 val)
 413{
 414        val = (__force u32)cpu_to_virtio32(vdev, val);
 415        vdev->config->set(vdev, offset, &val, sizeof(val));
 416}
 417
 418static inline u64 virtio_cread64(struct virtio_device *vdev,
 419                                 unsigned int offset)
 420{
 421        u64 ret;
 422        __virtio_cread_many(vdev, offset, &ret, 1, sizeof(ret));
 423        return virtio64_to_cpu(vdev, (__force __virtio64)ret);
 424}
 425
 426static inline void virtio_cwrite64(struct virtio_device *vdev,
 427                                   unsigned int offset, u64 val)
 428{
 429        val = (__force u64)cpu_to_virtio64(vdev, val);
 430        vdev->config->set(vdev, offset, &val, sizeof(val));
 431}
 432
 433/* Conditional config space accessors. */
 434#define virtio_cread_feature(vdev, fbit, structname, member, ptr)       \
 435        ({                                                              \
 436                int _r = 0;                                             \
 437                if (!virtio_has_feature(vdev, fbit))                    \
 438                        _r = -ENOENT;                                   \
 439                else                                                    \
 440                        virtio_cread((vdev), structname, member, ptr);  \
 441                _r;                                                     \
 442        })
 443
 444#endif /* _LINUX_VIRTIO_CONFIG_H */
 445