/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright ( c ) 2024 - 2025 , NVIDIA CORPORATION & AFFILIATES
*/
#ifndef __LINUX_FWCTL_H
#define __LINUX_FWCTL_H
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/cleanup.h>
#include <uapi/fwctl/fwctl.h>
struct fwctl_device;
struct fwctl_uctx;
/**
* struct fwctl_ops - Driver provided operations
*
* fwctl_unregister ( ) will wait until all excuting ops are completed before it
* returns . Drivers should be mindful to not let their ops run for too long as
* it will block device hot unplug and module unloading .
*/
struct fwctl_ops {
/**
* @ device_type : The drivers assigned device_type number . This is uABI .
*/
enum fwctl_device_type device_type;
/**
* @ uctx_size : The size of the fwctl_uctx struct to allocate . The first
* bytes of this memory will be a fwctl_uctx . The driver can use the
* remaining bytes as its private memory .
*/
size_t uctx_size;
/**
* @ open_uctx : Called when a file descriptor is opened before the uctx
* is ever used .
*/
int (*open_uctx)(struct fwctl_uctx *uctx);
/**
* @ close_uctx : Called when the uctx is destroyed , usually when the FD
* is closed .
*/
void (*close_uctx)(struct fwctl_uctx *uctx);
/**
* @ info : Implement FWCTL_INFO . Return a kmalloc ( ) memory that is copied
* to out_device_data . On input length indicates the size of the user
* buffer on output it indicates the size of the memory . The driver can
* ignore length on input , the core code will handle everything .
*/
void *(*info)(struct fwctl_uctx *uctx, size_t *length);
/**
* @ fw_rpc : Implement FWCTL_RPC . Deliver rpc_in / in_len to the FW and
* return the response and set out_len . rpc_in can be returned as the
* response pointer . Otherwise the returned pointer is freed with
* kvfree ( ) .
*/
void *(*fw_rpc)(struct fwctl_uctx *uctx, enum fwctl_rpc_scope scope,
void *rpc_in, size_t in_len, size_t *out_len);
};
/**
* struct fwctl_device - Per - driver registration struct
* @ dev : The sysfs ( class / fwctl / fwctlXX ) device
*
* Each driver instance will have one of these structs with the driver private
* data following immediately after . This struct is refcounted , it is freed by
* calling fwctl_put ( ) .
*/
struct fwctl_device {
struct device dev;
/* private: */
struct cdev cdev;
/* Protect uctx_list */
struct mutex uctx_list_lock;
struct list_head uctx_list;
/*
* Protect ops , held for write when ops becomes NULL during unregister ,
* held for read whenever ops is loaded or an ops function is running .
*/
struct rw_semaphore registration_lock;
const struct fwctl_ops *ops;
};
struct fwctl_device *_fwctl_alloc_device(struct device *parent,
const struct fwctl_ops *ops,
size_t size);
/**
* fwctl_alloc_device - Allocate a fwctl
* @ parent : Physical device that provides the FW interface
* @ ops : Driver ops to register
* @ drv_struct : ' struct driver_fwctl ' that holds the struct fwctl_device
* @ member : Name of the struct fwctl_device in @ drv_struct
*
* This allocates and initializes the fwctl_device embedded in the drv_struct .
* Upon success the pointer must be freed via fwctl_put ( ) . Returns a ' drv_struct
* \ * ' on success , NULL on error .
*/
#define fwctl_alloc_device(parent, ops, drv_struct, member) \
({ \
static_assert(__same_type(struct fwctl_device, \
((drv_struct *)NULL)->member)); \
static_assert(offsetof(drv_struct, member) == 0 ); \
(drv_struct *)_fwctl_alloc_device(parent, ops, \
sizeof (drv_struct)); \
})
static inline struct fwctl_device *fwctl_get(struct fwctl_device *fwctl)
{
get_device(&fwctl->dev);
return fwctl;
}
static inline void fwctl_put(struct fwctl_device *fwctl)
{
put_device(&fwctl->dev);
}
DEFINE_FREE(fwctl, struct fwctl_device *, if (_T) fwctl_put(_T));
int fwctl_register(struct fwctl_device *fwctl);
void fwctl_unregister(struct fwctl_device *fwctl);
/**
* struct fwctl_uctx - Per user FD context
* @ fwctl : fwctl instance that owns the context
*
* Every FD opened by userspace will get a unique context allocation . Any driver
* private data will follow immediately after .
*/
struct fwctl_uctx {
struct fwctl_device *fwctl;
/* private: */
/* Head at fwctl_device::uctx_list */
struct list_head uctx_list_entry;
};
#endif
Messung V0.5 in Prozent C=89 H=100 G=94
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland