root/include/linux/virtio_config.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __virtio_test_bit
  2. __virtio_set_bit
  3. __virtio_clear_bit
  4. virtio_has_feature
  5. virtio_has_iommu_quirk
  6. virtio_find_single_vq
  7. virtio_find_vqs
  8. virtio_find_vqs_ctx
  9. virtio_device_ready
  10. virtio_bus_name
  11. virtqueue_set_affinity
  12. virtio_is_little_endian
  13. virtio16_to_cpu
  14. cpu_to_virtio16
  15. virtio32_to_cpu
  16. cpu_to_virtio32
  17. virtio64_to_cpu
  18. cpu_to_virtio64
  19. __virtio_cread_many
  20. virtio_cread_bytes
  21. virtio_cread8
  22. virtio_cwrite8
  23. virtio_cread16
  24. virtio_cwrite16
  25. virtio_cread32
  26. virtio_cwrite32
  27. virtio_cread64
  28. virtio_cwrite64

   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 
  11 struct 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  */
  69 typedef void vq_callback_t(struct virtqueue *);
  70 struct 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. */
  94 void 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  */
 104 static 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  */
 121 static 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  */
 138 static 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  */
 155 static 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  */
 168 static 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 
 177 static inline
 178 struct 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 
 191 static inline
 192 int 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 
 200 static inline
 201 int 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  */
 218 static inline
 219 void 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 
 227 static inline
 228 const 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  */
 244 static inline
 245 int 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 
 253 static 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 */
 260 static 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 
 265 static 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 
 270 static 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 
 275 static 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 
 280 static 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 
 285 static 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. */
 355 static 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 
 376 static 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 
 383 static 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 
 392 static 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 
 399 static 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 
 409 static 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 
 417 static 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 
 427 static 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 
 435 static 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 
 443 static 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 */

/* [<][>][^][v][top][bottom][index][help] */