summaryrefslogtreecommitdiff
path: root/include/linux/dibs.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/dibs.h')
-rw-r--r--include/linux/dibs.h89
1 files changed, 87 insertions, 2 deletions
diff --git a/include/linux/dibs.h b/include/linux/dibs.h
index c12db19c98c0..805ab33271b5 100644
--- a/include/linux/dibs.h
+++ b/include/linux/dibs.h
@@ -34,14 +34,45 @@
* clients.
*/
+struct dibs_dev;
+
/* DIBS client
* -----------
*/
#define MAX_DIBS_CLIENTS 8
+/* All dibs clients have access to all dibs devices.
+ * A dibs client provides the following functions to be called by dibs layer or
+ * dibs device drivers:
+ */
+struct dibs_client_ops {
+ /**
+ * add_dev() - add a dibs device
+ * @dev: device that was added
+ *
+ * Will be called during dibs_register_client() for all existing
+ * dibs devices and whenever a new dibs device is registered.
+ * dev is usable until dibs_client.remove() is called.
+ * *dev is protected by device refcounting.
+ */
+ void (*add_dev)(struct dibs_dev *dev);
+ /**
+ * del_dev() - remove a dibs device
+ * @dev: device to be removed
+ *
+ * Will be called whenever a dibs device is removed.
+ * Will be called during dibs_unregister_client() for all existing
+ * dibs devices and whenever a dibs device is unregistered.
+ * The device has already stopped initiative for this client:
+ * No new handlers will be started.
+ * The device is no longer usable by this client after this call.
+ */
+ void (*del_dev)(struct dibs_dev *dev);
+};
struct dibs_client {
/* client name for logging and debugging purposes */
const char *name;
+ const struct dibs_client_ops *ops;
/* client index - provided and used by dibs layer */
u8 id;
};
@@ -52,6 +83,7 @@ struct dibs_client {
* dibs_register_client() - register a client with dibs layer
* @client: this client
*
+ * Will call client->ops->add_dev() for all existing dibs devices.
* Return: zero on success.
*/
int dibs_register_client(struct dibs_client *client);
@@ -59,21 +91,74 @@ int dibs_register_client(struct dibs_client *client);
* dibs_unregister_client() - unregister a client with dibs layer
* @client: this client
*
+ * Will call client->ops->del_dev() for all existing dibs devices.
* Return: zero on success.
*/
int dibs_unregister_client(struct dibs_client *client);
+/* dibs clients can call dibs device ops. */
+
/* DIBS devices
* ------------
*/
+
+/* Defined fabric id / CHID for all loopback devices:
+ * All dibs loopback devices report this fabric id. In this case devices with
+ * the same fabric id can NOT communicate via dibs. Only loopback devices with
+ * the same dibs device gid can communicate (=same device with itself).
+ */
+#define DIBS_LOOPBACK_FABRIC 0xFFFF
+
+/* A dibs device provides the following functions to be called by dibs clients.
+ * They are mandatory, unless marked 'optional'.
+ */
+struct dibs_dev_ops {
+ /**
+ * get_fabric_id()
+ * @dev: local dibs device
+ *
+ * Only devices on the same dibs fabric can communicate. Fabric_id is
+ * unique inside the same HW system. Use fabric_id for fast negative
+ * checks, but only query_remote_gid() can give a reliable positive
+ * answer:
+ * Different fabric_id: dibs is not possible
+ * Same fabric_id: dibs may be possible or not
+ * (e.g. different HW systems)
+ * EXCEPTION: DIBS_LOOPBACK_FABRIC denotes an ism_loopback device
+ * that can only communicate with itself. Use dibs_dev.gid
+ * or query_remote_gid()to determine whether sender and
+ * receiver use the same ism_loopback device.
+ * Return: 2 byte dibs fabric id
+ */
+ u16 (*get_fabric_id)(struct dibs_dev *dev);
+};
+
struct dibs_dev {
struct list_head list;
+ /* To be filled by device driver, before calling dibs_dev_add(): */
+ const struct dibs_dev_ops *ops;
+ /* priv pointer for device driver */
+ void *drv_priv;
+
+ /* priv pointer per client; for client usage only */
+ void *priv[MAX_DIBS_CLIENTS];
};
+static inline void dibs_set_priv(struct dibs_dev *dev,
+ struct dibs_client *client, void *priv)
+{
+ dev->priv[client->id] = priv;
+}
+
+static inline void *dibs_get_priv(struct dibs_dev *dev,
+ struct dibs_client *client)
+{
+ return dev->priv[client->id];
+}
+
/* ------- End of client-only functions ----------- */
-/*
- * Functions to be called by dibs device drivers:
+/* Functions to be called by dibs device drivers:
*/
/**
* dibs_dev_alloc() - allocate and reference device structure