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>
This commit is contained in:
parent
d324a2ca3f
commit
269726968f
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef _DIBS_H
|
||||
#define _DIBS_H
|
||||
|
||||
#include <linux/device.h>
|
||||
/* DIBS - Direct Internal Buffer Sharing - concept
|
||||
* -----------------------------------------------
|
||||
* In the case of multiple system sharing the same hardware, dibs fabrics can
|
||||
|
|
@ -62,4 +63,41 @@ int dibs_register_client(struct dibs_client *client);
|
|||
*/
|
||||
int dibs_unregister_client(struct dibs_client *client);
|
||||
|
||||
/* DIBS devices
|
||||
* ------------
|
||||
*/
|
||||
struct dibs_dev {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* ------- End of client-only functions ----------- */
|
||||
|
||||
/*
|
||||
* Functions to be called by dibs device drivers:
|
||||
*/
|
||||
/**
|
||||
* dibs_dev_alloc() - allocate and reference device structure
|
||||
*
|
||||
* The following fields will be valid upon successful return: dev
|
||||
* NOTE: Use put_device(dibs_get_dev(@dibs)) to give up your reference instead
|
||||
* of freeing @dibs @dev directly once you have successfully called this
|
||||
* function.
|
||||
* Return: Pointer to dibs device structure
|
||||
*/
|
||||
struct dibs_dev *dibs_dev_alloc(void);
|
||||
/**
|
||||
* dibs_dev_add() - register with dibs layer and all clients
|
||||
* @dibs: dibs device
|
||||
*
|
||||
* The following fields must be valid upon entry: dev, ops, drv_priv
|
||||
* All fields will be valid upon successful return.
|
||||
* Return: zero on success
|
||||
*/
|
||||
int dibs_dev_add(struct dibs_dev *dibs);
|
||||
/**
|
||||
* dibs_dev_del() - unregister from dibs layer and all clients
|
||||
* @dibs: dibs device
|
||||
*/
|
||||
void dibs_dev_del(struct dibs_dev *dibs);
|
||||
|
||||
#endif /* _DIBS_H */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct ism_dev {
|
|||
spinlock_t lock; /* protects the ism device */
|
||||
spinlock_t cmd_lock; /* serializes cmds */
|
||||
struct list_head list;
|
||||
struct dibs_dev *dibs;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
struct ism_sba *sba;
|
||||
|
|
|
|||
Loading…
Reference in New Issue