xref: /linux/drivers/dibs/dibs_main.c (revision d324a2ca3f8efd57f5839aa2690554a5cbb3586f)
135758b00SAlexandra Winter // SPDX-License-Identifier: GPL-2.0
235758b00SAlexandra Winter /*
335758b00SAlexandra Winter  *  DIBS - Direct Internal Buffer Sharing
435758b00SAlexandra Winter  *
535758b00SAlexandra Winter  *  Implementation of the DIBS class module
635758b00SAlexandra Winter  *
735758b00SAlexandra Winter  *  Copyright IBM Corp. 2025
835758b00SAlexandra Winter  */
935758b00SAlexandra Winter #define KMSG_COMPONENT "dibs"
1035758b00SAlexandra Winter #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
1135758b00SAlexandra Winter 
1235758b00SAlexandra Winter #include <linux/module.h>
1335758b00SAlexandra Winter #include <linux/types.h>
1435758b00SAlexandra Winter #include <linux/err.h>
1535758b00SAlexandra Winter #include <linux/dibs.h>
1635758b00SAlexandra Winter 
1735758b00SAlexandra Winter MODULE_DESCRIPTION("Direct Internal Buffer Sharing class");
1835758b00SAlexandra Winter MODULE_LICENSE("GPL");
1935758b00SAlexandra Winter 
2035758b00SAlexandra Winter /* use an array rather a list for fast mapping: */
2135758b00SAlexandra Winter static struct dibs_client *clients[MAX_DIBS_CLIENTS];
2235758b00SAlexandra Winter static u8 max_client;
23*d324a2caSAlexandra Winter static DEFINE_MUTEX(clients_lock);
24*d324a2caSAlexandra Winter 
25*d324a2caSAlexandra Winter int dibs_register_client(struct dibs_client *client)
26*d324a2caSAlexandra Winter {
27*d324a2caSAlexandra Winter 	int i, rc = -ENOSPC;
28*d324a2caSAlexandra Winter 
29*d324a2caSAlexandra Winter 	mutex_lock(&clients_lock);
30*d324a2caSAlexandra Winter 	for (i = 0; i < MAX_DIBS_CLIENTS; ++i) {
31*d324a2caSAlexandra Winter 		if (!clients[i]) {
32*d324a2caSAlexandra Winter 			clients[i] = client;
33*d324a2caSAlexandra Winter 			client->id = i;
34*d324a2caSAlexandra Winter 			if (i == max_client)
35*d324a2caSAlexandra Winter 				max_client++;
36*d324a2caSAlexandra Winter 			rc = 0;
37*d324a2caSAlexandra Winter 			break;
38*d324a2caSAlexandra Winter 		}
39*d324a2caSAlexandra Winter 	}
40*d324a2caSAlexandra Winter 	mutex_unlock(&clients_lock);
41*d324a2caSAlexandra Winter 
42*d324a2caSAlexandra Winter 	return rc;
43*d324a2caSAlexandra Winter }
44*d324a2caSAlexandra Winter EXPORT_SYMBOL_GPL(dibs_register_client);
45*d324a2caSAlexandra Winter 
46*d324a2caSAlexandra Winter int dibs_unregister_client(struct dibs_client *client)
47*d324a2caSAlexandra Winter {
48*d324a2caSAlexandra Winter 	int rc = 0;
49*d324a2caSAlexandra Winter 
50*d324a2caSAlexandra Winter 	mutex_lock(&clients_lock);
51*d324a2caSAlexandra Winter 	clients[client->id] = NULL;
52*d324a2caSAlexandra Winter 	if (client->id + 1 == max_client)
53*d324a2caSAlexandra Winter 		max_client--;
54*d324a2caSAlexandra Winter 	mutex_unlock(&clients_lock);
55*d324a2caSAlexandra Winter 	return rc;
56*d324a2caSAlexandra Winter }
57*d324a2caSAlexandra Winter EXPORT_SYMBOL_GPL(dibs_unregister_client);
5835758b00SAlexandra Winter 
5935758b00SAlexandra Winter static int __init dibs_init(void)
6035758b00SAlexandra Winter {
6135758b00SAlexandra Winter 	memset(clients, 0, sizeof(clients));
6235758b00SAlexandra Winter 	max_client = 0;
6335758b00SAlexandra Winter 
6435758b00SAlexandra Winter 	return 0;
6535758b00SAlexandra Winter }
6635758b00SAlexandra Winter 
6735758b00SAlexandra Winter static void __exit dibs_exit(void)
6835758b00SAlexandra Winter {
6935758b00SAlexandra Winter }
7035758b00SAlexandra Winter 
7135758b00SAlexandra Winter module_init(dibs_init);
7235758b00SAlexandra Winter module_exit(dibs_exit);
73