1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Functions for dibs loopback/loopback-ism device. 4 * 5 * Copyright (c) 2024, Alibaba Inc. 6 * 7 * Author: Wen Gu <guwen@linux.alibaba.com> 8 * Tony Lu <tonylu@linux.alibaba.com> 9 * 10 */ 11 12 #include <linux/dibs.h> 13 #include <linux/slab.h> 14 #include <linux/types.h> 15 16 #include "dibs_loopback.h" 17 18 /* global loopback device */ 19 static struct dibs_lo_dev *lo_dev; 20 21 static void dibs_lo_dev_exit(struct dibs_lo_dev *ldev) 22 { 23 dibs_dev_del(ldev->dibs); 24 } 25 26 static int dibs_lo_dev_probe(void) 27 { 28 struct dibs_lo_dev *ldev; 29 struct dibs_dev *dibs; 30 int ret; 31 32 ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 33 if (!ldev) 34 return -ENOMEM; 35 36 dibs = dibs_dev_alloc(); 37 if (!dibs) { 38 kfree(ldev); 39 return -ENOMEM; 40 } 41 42 ldev->dibs = dibs; 43 44 ret = dibs_dev_add(dibs); 45 if (ret) 46 goto err_reg; 47 lo_dev = ldev; 48 return 0; 49 50 err_reg: 51 /* pairs with dibs_dev_alloc() */ 52 kfree(dibs); 53 kfree(ldev); 54 55 return ret; 56 } 57 58 static void dibs_lo_dev_remove(void) 59 { 60 if (!lo_dev) 61 return; 62 63 dibs_lo_dev_exit(lo_dev); 64 /* pairs with dibs_dev_alloc() */ 65 kfree(lo_dev->dibs); 66 kfree(lo_dev); 67 lo_dev = NULL; 68 } 69 70 int dibs_loopback_init(void) 71 { 72 return dibs_lo_dev_probe(); 73 } 74 75 void dibs_loopback_exit(void) 76 { 77 dibs_lo_dev_remove(); 78 } 79