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