diff options
| author | Alexandra Winter <wintera@linux.ibm.com> | 2025-09-18 13:04:51 +0200 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2025-09-23 11:13:21 +0200 |
| commit | 269726968f95ebc00e3a47f91eebd6818991d6fa (patch) | |
| tree | 2597d41085852dff4d577343a34542def2b21559 /drivers | |
| parent | dibs: Register smc as dibs_client (diff) | |
| download | linux-269726968f95ebc00e3a47f91eebd6818991d6fa.tar.gz linux-269726968f95ebc00e3a47f91eebd6818991d6fa.zip | |
dibs: Register ism as dibs device
Register ism devices with the dibs layer. Follow-on patches will move
functionality to the dibs layer.
As DIBS is only a shim layer without any dependencies, we can depend ISM
on DIBS without adding indirect dependencies. A follow-on patch will
remove implication of SMC by ISM.
Define struct dibs_dev. Follow-on patches will move more content into
dibs_dev. The goal of follow-on patches is that ism_dev will only
contain fields that are special for this device driver. The same concept
will apply to other dibs device drivers.
Define dibs_dev_alloc(), dibs_dev_add() and dibs_dev_del() to be called
by dibs device drivers and call them from ism_drv.c
Use ism_dev.dibs for a pointer to dibs_dev.
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20250918110500.1731261-6-wintera@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dibs/dibs_main.c | 38 | ||||
| -rw-r--r-- | drivers/s390/net/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/s390/net/ism.h | 1 | ||||
| -rw-r--r-- | drivers/s390/net/ism_drv.c | 83 |
4 files changed, 92 insertions, 32 deletions
diff --git a/drivers/dibs/dibs_main.c b/drivers/dibs/dibs_main.c index a5d2be9c3246..2f420e077417 100644 --- a/drivers/dibs/dibs_main.c +++ b/drivers/dibs/dibs_main.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/err.h> #include <linux/dibs.h> @@ -21,6 +22,15 @@ MODULE_LICENSE("GPL"); static struct dibs_client *clients[MAX_DIBS_CLIENTS]; static u8 max_client; static DEFINE_MUTEX(clients_lock); +struct dibs_dev_list { + struct list_head list; + struct mutex mutex; /* protects dibs device list */ +}; + +static struct dibs_dev_list dibs_dev_list = { + .list = LIST_HEAD_INIT(dibs_dev_list.list), + .mutex = __MUTEX_INITIALIZER(dibs_dev_list.mutex), +}; int dibs_register_client(struct dibs_client *client) { @@ -56,6 +66,34 @@ int dibs_unregister_client(struct dibs_client *client) } EXPORT_SYMBOL_GPL(dibs_unregister_client); +struct dibs_dev *dibs_dev_alloc(void) +{ + struct dibs_dev *dibs; + + dibs = kzalloc(sizeof(*dibs), GFP_KERNEL); + + return dibs; +} +EXPORT_SYMBOL_GPL(dibs_dev_alloc); + +int dibs_dev_add(struct dibs_dev *dibs) +{ + mutex_lock(&dibs_dev_list.mutex); + list_add(&dibs->list, &dibs_dev_list.list); + mutex_unlock(&dibs_dev_list.mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(dibs_dev_add); + +void dibs_dev_del(struct dibs_dev *dibs) +{ + mutex_lock(&dibs_dev_list.mutex); + list_del_init(&dibs->list); + mutex_unlock(&dibs_dev_list.mutex); +} +EXPORT_SYMBOL_GPL(dibs_dev_del); + static int __init dibs_init(void) { memset(clients, 0, sizeof(clients)); diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 2b43f6f28362..92985f595d59 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -81,7 +81,7 @@ config CCWGROUP config ISM tristate "Support for ISM vPCI Adapter" - depends on PCI + depends on PCI && DIBS imply SMC default n help diff --git a/drivers/s390/net/ism.h b/drivers/s390/net/ism.h index b5b03db52fce..3078779fa71e 100644 --- a/drivers/s390/net/ism.h +++ b/drivers/s390/net/ism.h @@ -5,6 +5,7 @@ #include <linux/spinlock.h> #include <linux/types.h> #include <linux/pci.h> +#include <linux/dibs.h> #include <linux/ism.h> #include <net/smc.h> #include <asm/pci_insn.h> diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 6cd60b174315..8ecd0cccc7e8 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -599,8 +599,39 @@ static void ism_dev_release(struct device *dev) kfree(ism); } +static void ism_dev_exit(struct ism_dev *ism) +{ + struct pci_dev *pdev = ism->pdev; + unsigned long flags; + int i; + + spin_lock_irqsave(&ism->lock, flags); + for (i = 0; i < max_client; ++i) + ism->subs[i] = NULL; + spin_unlock_irqrestore(&ism->lock, flags); + + mutex_lock(&ism_dev_list.mutex); + mutex_lock(&clients_lock); + for (i = 0; i < max_client; ++i) { + if (clients[i]) + clients[i]->remove(ism); + } + mutex_unlock(&clients_lock); + + if (ism_v2_capable) + ism_del_vlan_id(ism, ISM_RESERVED_VLANID); + unregister_ieq(ism); + unregister_sba(ism); + free_irq(pci_irq_vector(pdev, 0), ism); + kfree(ism->sba_client_arr); + pci_free_irq_vectors(pdev); + list_del_init(&ism->list); + mutex_unlock(&ism_dev_list.mutex); +} + static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct dibs_dev *dibs; struct ism_dev *ism; int ret; @@ -636,12 +667,28 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) dma_set_max_seg_size(&pdev->dev, SZ_1M); pci_set_master(pdev); + dibs = dibs_dev_alloc(); + if (!dibs) { + ret = -ENOMEM; + goto err_resource; + } + ism->dibs = dibs; + ret = ism_dev_init(ism); if (ret) - goto err_resource; + goto err_dibs; + + ret = dibs_dev_add(dibs); + if (ret) + goto err_ism; return 0; +err_ism: + ism_dev_exit(ism); +err_dibs: + /* pairs with dibs_dev_alloc() */ + kfree(dibs); err_resource: pci_release_mem_regions(pdev); err_disable: @@ -655,41 +702,15 @@ err_dev: return ret; } -static void ism_dev_exit(struct ism_dev *ism) -{ - struct pci_dev *pdev = ism->pdev; - unsigned long flags; - int i; - - spin_lock_irqsave(&ism->lock, flags); - for (i = 0; i < max_client; ++i) - ism->subs[i] = NULL; - spin_unlock_irqrestore(&ism->lock, flags); - - mutex_lock(&ism_dev_list.mutex); - mutex_lock(&clients_lock); - for (i = 0; i < max_client; ++i) { - if (clients[i]) - clients[i]->remove(ism); - } - mutex_unlock(&clients_lock); - - if (ism_v2_capable) - ism_del_vlan_id(ism, ISM_RESERVED_VLANID); - unregister_ieq(ism); - unregister_sba(ism); - free_irq(pci_irq_vector(pdev, 0), ism); - kfree(ism->sba_client_arr); - pci_free_irq_vectors(pdev); - list_del_init(&ism->list); - mutex_unlock(&ism_dev_list.mutex); -} - static void ism_remove(struct pci_dev *pdev) { struct ism_dev *ism = dev_get_drvdata(&pdev->dev); + struct dibs_dev *dibs = ism->dibs; + dibs_dev_del(dibs); ism_dev_exit(ism); + /* pairs with dibs_dev_alloc() */ + kfree(dibs); pci_release_mem_regions(pdev); pci_disable_device(pdev); |
