1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * DIBS - Direct Internal Buffer Sharing 4 * 5 * Implementation of the DIBS class module 6 * 7 * Copyright IBM Corp. 2025 8 */ 9 #define KMSG_COMPONENT "dibs" 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 12 #include <linux/module.h> 13 #include <linux/types.h> 14 #include <linux/slab.h> 15 #include <linux/err.h> 16 #include <linux/dibs.h> 17 18 MODULE_DESCRIPTION("Direct Internal Buffer Sharing class"); 19 MODULE_LICENSE("GPL"); 20 21 /* use an array rather a list for fast mapping: */ 22 static struct dibs_client *clients[MAX_DIBS_CLIENTS]; 23 static u8 max_client; 24 static DEFINE_MUTEX(clients_lock); 25 struct dibs_dev_list { 26 struct list_head list; 27 struct mutex mutex; /* protects dibs device list */ 28 }; 29 30 static struct dibs_dev_list dibs_dev_list = { 31 .list = LIST_HEAD_INIT(dibs_dev_list.list), 32 .mutex = __MUTEX_INITIALIZER(dibs_dev_list.mutex), 33 }; 34 35 int dibs_register_client(struct dibs_client *client) 36 { 37 int i, rc = -ENOSPC; 38 39 mutex_lock(&clients_lock); 40 for (i = 0; i < MAX_DIBS_CLIENTS; ++i) { 41 if (!clients[i]) { 42 clients[i] = client; 43 client->id = i; 44 if (i == max_client) 45 max_client++; 46 rc = 0; 47 break; 48 } 49 } 50 mutex_unlock(&clients_lock); 51 52 return rc; 53 } 54 EXPORT_SYMBOL_GPL(dibs_register_client); 55 56 int dibs_unregister_client(struct dibs_client *client) 57 { 58 int rc = 0; 59 60 mutex_lock(&clients_lock); 61 clients[client->id] = NULL; 62 if (client->id + 1 == max_client) 63 max_client--; 64 mutex_unlock(&clients_lock); 65 return rc; 66 } 67 EXPORT_SYMBOL_GPL(dibs_unregister_client); 68 69 struct dibs_dev *dibs_dev_alloc(void) 70 { 71 struct dibs_dev *dibs; 72 73 dibs = kzalloc(sizeof(*dibs), GFP_KERNEL); 74 75 return dibs; 76 } 77 EXPORT_SYMBOL_GPL(dibs_dev_alloc); 78 79 int dibs_dev_add(struct dibs_dev *dibs) 80 { 81 mutex_lock(&dibs_dev_list.mutex); 82 list_add(&dibs->list, &dibs_dev_list.list); 83 mutex_unlock(&dibs_dev_list.mutex); 84 85 return 0; 86 } 87 EXPORT_SYMBOL_GPL(dibs_dev_add); 88 89 void dibs_dev_del(struct dibs_dev *dibs) 90 { 91 mutex_lock(&dibs_dev_list.mutex); 92 list_del_init(&dibs->list); 93 mutex_unlock(&dibs_dev_list.mutex); 94 } 95 EXPORT_SYMBOL_GPL(dibs_dev_del); 96 97 static int __init dibs_init(void) 98 { 99 memset(clients, 0, sizeof(clients)); 100 max_client = 0; 101 102 return 0; 103 } 104 105 static void __exit dibs_exit(void) 106 { 107 } 108 109 module_init(dibs_init); 110 module_exit(dibs_exit); 111