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