net/smc: Register SMC-D as ISM client
Register the smc module with the new ism device driver API. This is the second part of a bigger overhaul of the interfaces between SMC and ISM. Signed-off-by: Stefan Raspl <raspl@linux.ibm.com> Signed-off-by: Jan Karcher <jaka@linux.ibm.com> Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
89e7d2ba61
commit
8747716f39
@@ -642,10 +642,6 @@ static int ism_dev_init(struct ism_dev *ism)
|
|||||||
list_add(&ism->list, &ism_dev_list.list);
|
list_add(&ism->list, &ism_dev_list.list);
|
||||||
mutex_unlock(&ism_dev_list.mutex);
|
mutex_unlock(&ism_dev_list.mutex);
|
||||||
|
|
||||||
ret = smcd_register_dev(ism->smcd);
|
|
||||||
if (ret)
|
|
||||||
goto unreg_ieq;
|
|
||||||
|
|
||||||
query_info(ism);
|
query_info(ism);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -748,7 +744,6 @@ static void ism_dev_exit(struct ism_dev *ism)
|
|||||||
|
|
||||||
wait_event(ism->waitq, !atomic_read(&ism->free_clients_cnt));
|
wait_event(ism->waitq, !atomic_read(&ism->free_clients_cnt));
|
||||||
|
|
||||||
smcd_unregister_dev(ism->smcd);
|
|
||||||
if (SYSTEM_EID.serial_number[0] != '0' ||
|
if (SYSTEM_EID.serial_number[0] != '0' ||
|
||||||
SYSTEM_EID.type[0] != '0')
|
SYSTEM_EID.type[0] != '0')
|
||||||
ism_del_vlan_id(ism->smcd, ISM_RESERVED_VLANID);
|
ism_del_vlan_id(ism->smcd, ISM_RESERVED_VLANID);
|
||||||
|
|||||||
+1
-4
@@ -90,9 +90,6 @@ struct smcd_dev {
|
|||||||
|
|
||||||
struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
|
struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
|
||||||
const struct smcd_ops *ops, int max_dmbs);
|
const struct smcd_ops *ops, int max_dmbs);
|
||||||
int smcd_register_dev(struct smcd_dev *smcd);
|
|
||||||
void smcd_unregister_dev(struct smcd_dev *smcd);
|
|
||||||
void smcd_free_dev(struct smcd_dev *smcd);
|
void smcd_free_dev(struct smcd_dev *smcd);
|
||||||
void smcd_handle_event(struct smcd_dev *dev, struct ism_event *event);
|
|
||||||
void smcd_handle_irq(struct smcd_dev *dev, unsigned int bit, u16 dmbemask);
|
|
||||||
#endif /* _SMC_H */
|
#endif /* _SMC_H */
|
||||||
|
|||||||
+6
-2
@@ -3382,12 +3382,14 @@ static int __init smc_init(void)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto out_pernet_subsys;
|
goto out_pernet_subsys;
|
||||||
|
|
||||||
smc_ism_init();
|
rc = smc_ism_init();
|
||||||
|
if (rc)
|
||||||
|
goto out_pernet_subsys_stat;
|
||||||
smc_clc_init();
|
smc_clc_init();
|
||||||
|
|
||||||
rc = smc_nl_init();
|
rc = smc_nl_init();
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_pernet_subsys_stat;
|
goto out_ism;
|
||||||
|
|
||||||
rc = smc_pnet_init();
|
rc = smc_pnet_init();
|
||||||
if (rc)
|
if (rc)
|
||||||
@@ -3480,6 +3482,8 @@ out_pnet:
|
|||||||
smc_pnet_exit();
|
smc_pnet_exit();
|
||||||
out_nl:
|
out_nl:
|
||||||
smc_nl_exit();
|
smc_nl_exit();
|
||||||
|
out_ism:
|
||||||
|
smc_ism_exit();
|
||||||
out_pernet_subsys_stat:
|
out_pernet_subsys_stat:
|
||||||
unregister_pernet_subsys(&smc_net_stat_ops);
|
unregister_pernet_subsys(&smc_net_stat_ops);
|
||||||
out_pernet_subsys:
|
out_pernet_subsys:
|
||||||
|
|||||||
@@ -2595,6 +2595,7 @@ static int smc_core_reboot_event(struct notifier_block *this,
|
|||||||
{
|
{
|
||||||
smc_lgrs_shutdown();
|
smc_lgrs_shutdown();
|
||||||
smc_ib_unregister_client();
|
smc_ib_unregister_client();
|
||||||
|
smc_ism_exit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+59
-23
@@ -17,6 +17,7 @@
|
|||||||
#include "smc_ism.h"
|
#include "smc_ism.h"
|
||||||
#include "smc_pnet.h"
|
#include "smc_pnet.h"
|
||||||
#include "smc_netlink.h"
|
#include "smc_netlink.h"
|
||||||
|
#include "linux/ism.h"
|
||||||
|
|
||||||
struct smcd_dev_list smcd_dev_list = {
|
struct smcd_dev_list smcd_dev_list = {
|
||||||
.list = LIST_HEAD_INIT(smcd_dev_list.list),
|
.list = LIST_HEAD_INIT(smcd_dev_list.list),
|
||||||
@@ -26,6 +27,20 @@ struct smcd_dev_list smcd_dev_list = {
|
|||||||
static bool smc_ism_v2_capable;
|
static bool smc_ism_v2_capable;
|
||||||
static u8 smc_ism_v2_system_eid[SMC_MAX_EID_LEN];
|
static u8 smc_ism_v2_system_eid[SMC_MAX_EID_LEN];
|
||||||
|
|
||||||
|
static void smcd_register_dev(struct ism_dev *ism);
|
||||||
|
static void smcd_unregister_dev(struct ism_dev *ism);
|
||||||
|
static void smcd_handle_event(struct ism_dev *ism, struct ism_event *event);
|
||||||
|
static void smcd_handle_irq(struct ism_dev *ism, unsigned int dmbno,
|
||||||
|
u16 dmbemask);
|
||||||
|
|
||||||
|
static struct ism_client smc_ism_client = {
|
||||||
|
.name = "SMC-D",
|
||||||
|
.add = smcd_register_dev,
|
||||||
|
.remove = smcd_unregister_dev,
|
||||||
|
.handle_event = smcd_handle_event,
|
||||||
|
.handle_irq = smcd_handle_irq,
|
||||||
|
};
|
||||||
|
|
||||||
/* Test if an ISM communication is possible - same CPC */
|
/* Test if an ISM communication is possible - same CPC */
|
||||||
int smc_ism_cantalk(u64 peer_gid, unsigned short vlan_id, struct smcd_dev *smcd)
|
int smc_ism_cantalk(u64 peer_gid, unsigned short vlan_id, struct smcd_dev *smcd)
|
||||||
{
|
{
|
||||||
@@ -409,8 +424,6 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
|
|||||||
device_initialize(&smcd->dev);
|
device_initialize(&smcd->dev);
|
||||||
dev_set_name(&smcd->dev, name);
|
dev_set_name(&smcd->dev, name);
|
||||||
smcd->ops = ops;
|
smcd->ops = ops;
|
||||||
if (smc_pnetid_by_dev_port(parent, 0, smcd->pnetid))
|
|
||||||
smc_pnetid_by_table_smcd(smcd);
|
|
||||||
|
|
||||||
spin_lock_init(&smcd->lock);
|
spin_lock_init(&smcd->lock);
|
||||||
spin_lock_init(&smcd->lgr_lock);
|
spin_lock_init(&smcd->lgr_lock);
|
||||||
@@ -421,9 +434,25 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smcd_alloc_dev);
|
EXPORT_SYMBOL_GPL(smcd_alloc_dev);
|
||||||
|
|
||||||
int smcd_register_dev(struct smcd_dev *smcd)
|
void smcd_free_dev(struct smcd_dev *smcd)
|
||||||
{
|
{
|
||||||
int rc;
|
put_device(&smcd->dev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(smcd_free_dev);
|
||||||
|
|
||||||
|
static void smcd_register_dev(struct ism_dev *ism)
|
||||||
|
{
|
||||||
|
const struct smcd_ops *ops = NULL;
|
||||||
|
struct smcd_dev *smcd;
|
||||||
|
|
||||||
|
smcd = smcd_alloc_dev(&ism->pdev->dev, dev_name(&ism->pdev->dev), ops,
|
||||||
|
ISM_NR_DMBS);
|
||||||
|
if (!smcd)
|
||||||
|
return;
|
||||||
|
smcd->priv = ism;
|
||||||
|
ism_set_priv(ism, &smc_ism_client, smcd);
|
||||||
|
if (smc_pnetid_by_dev_port(&ism->pdev->dev, 0, smcd->pnetid))
|
||||||
|
smc_pnetid_by_table_smcd(smcd);
|
||||||
|
|
||||||
mutex_lock(&smcd_dev_list.mutex);
|
mutex_lock(&smcd_dev_list.mutex);
|
||||||
if (list_empty(&smcd_dev_list.list)) {
|
if (list_empty(&smcd_dev_list.list)) {
|
||||||
@@ -447,19 +476,20 @@ int smcd_register_dev(struct smcd_dev *smcd)
|
|||||||
dev_name(&smcd->dev), smcd->pnetid,
|
dev_name(&smcd->dev), smcd->pnetid,
|
||||||
smcd->pnetid_by_user ? " (user defined)" : "");
|
smcd->pnetid_by_user ? " (user defined)" : "");
|
||||||
|
|
||||||
rc = device_add(&smcd->dev);
|
if (device_add(&smcd->dev)) {
|
||||||
if (rc) {
|
|
||||||
mutex_lock(&smcd_dev_list.mutex);
|
mutex_lock(&smcd_dev_list.mutex);
|
||||||
list_del(&smcd->list);
|
list_del(&smcd->list);
|
||||||
mutex_unlock(&smcd_dev_list.mutex);
|
mutex_unlock(&smcd_dev_list.mutex);
|
||||||
|
smcd_free_dev(smcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smcd_register_dev);
|
|
||||||
|
|
||||||
void smcd_unregister_dev(struct smcd_dev *smcd)
|
static void smcd_unregister_dev(struct ism_dev *ism)
|
||||||
{
|
{
|
||||||
|
struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client);
|
||||||
|
|
||||||
pr_warn_ratelimited("smc: removing smcd device %s\n",
|
pr_warn_ratelimited("smc: removing smcd device %s\n",
|
||||||
dev_name(&smcd->dev));
|
dev_name(&smcd->dev));
|
||||||
smcd->going_away = 1;
|
smcd->going_away = 1;
|
||||||
@@ -471,16 +501,9 @@ void smcd_unregister_dev(struct smcd_dev *smcd)
|
|||||||
|
|
||||||
device_del(&smcd->dev);
|
device_del(&smcd->dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smcd_unregister_dev);
|
|
||||||
|
|
||||||
void smcd_free_dev(struct smcd_dev *smcd)
|
|
||||||
{
|
|
||||||
put_device(&smcd->dev);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(smcd_free_dev);
|
|
||||||
|
|
||||||
/* SMCD Device event handler. Called from ISM device interrupt handler.
|
/* SMCD Device event handler. Called from ISM device interrupt handler.
|
||||||
* Parameters are smcd device pointer,
|
* Parameters are ism device pointer,
|
||||||
* - event->type (0 --> DMB, 1 --> GID),
|
* - event->type (0 --> DMB, 1 --> GID),
|
||||||
* - event->code (event code),
|
* - event->code (event code),
|
||||||
* - event->tok (either DMB token when event type 0, or GID when event type 1)
|
* - event->tok (either DMB token when event type 0, or GID when event type 1)
|
||||||
@@ -490,8 +513,9 @@ EXPORT_SYMBOL_GPL(smcd_free_dev);
|
|||||||
* Context:
|
* Context:
|
||||||
* - Function called in IRQ context from ISM device driver event handler.
|
* - Function called in IRQ context from ISM device driver event handler.
|
||||||
*/
|
*/
|
||||||
void smcd_handle_event(struct smcd_dev *smcd, struct ism_event *event)
|
static void smcd_handle_event(struct ism_dev *ism, struct ism_event *event)
|
||||||
{
|
{
|
||||||
|
struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client);
|
||||||
struct smc_ism_event_work *wrk;
|
struct smc_ism_event_work *wrk;
|
||||||
|
|
||||||
if (smcd->going_away)
|
if (smcd->going_away)
|
||||||
@@ -505,17 +529,18 @@ void smcd_handle_event(struct smcd_dev *smcd, struct ism_event *event)
|
|||||||
wrk->event = *event;
|
wrk->event = *event;
|
||||||
queue_work(smcd->event_wq, &wrk->work);
|
queue_work(smcd->event_wq, &wrk->work);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smcd_handle_event);
|
|
||||||
|
|
||||||
/* SMCD Device interrupt handler. Called from ISM device interrupt handler.
|
/* SMCD Device interrupt handler. Called from ISM device interrupt handler.
|
||||||
* Parameters are smcd device pointer, DMB number, and the DMBE bitmask.
|
* Parameters are the ism device pointer, DMB number, and the DMBE bitmask.
|
||||||
* Find the connection and schedule the tasklet for this connection.
|
* Find the connection and schedule the tasklet for this connection.
|
||||||
*
|
*
|
||||||
* Context:
|
* Context:
|
||||||
* - Function called in IRQ context from ISM device driver IRQ handler.
|
* - Function called in IRQ context from ISM device driver IRQ handler.
|
||||||
*/
|
*/
|
||||||
void smcd_handle_irq(struct smcd_dev *smcd, unsigned int dmbno, u16 dmbemask)
|
static void smcd_handle_irq(struct ism_dev *ism, unsigned int dmbno,
|
||||||
|
u16 dmbemask)
|
||||||
{
|
{
|
||||||
|
struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client);
|
||||||
struct smc_connection *conn = NULL;
|
struct smc_connection *conn = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
@@ -525,10 +550,21 @@ void smcd_handle_irq(struct smcd_dev *smcd, unsigned int dmbno, u16 dmbemask)
|
|||||||
tasklet_schedule(&conn->rx_tsklet);
|
tasklet_schedule(&conn->rx_tsklet);
|
||||||
spin_unlock_irqrestore(&smcd->lock, flags);
|
spin_unlock_irqrestore(&smcd->lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smcd_handle_irq);
|
|
||||||
|
|
||||||
void __init smc_ism_init(void)
|
int smc_ism_init(void)
|
||||||
{
|
{
|
||||||
smc_ism_v2_capable = false;
|
smc_ism_v2_capable = false;
|
||||||
memset(smc_ism_v2_system_eid, 0, SMC_MAX_EID_LEN);
|
memset(smc_ism_v2_system_eid, 0, SMC_MAX_EID_LEN);
|
||||||
|
#if IS_ENABLED(CONFIG_ISM)
|
||||||
|
return ism_register_client(&smc_ism_client);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void smc_ism_exit(void)
|
||||||
|
{
|
||||||
|
#if IS_ENABLED(CONFIG_ISM)
|
||||||
|
ism_unregister_client(&smc_ism_client);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -42,7 +42,8 @@ int smc_ism_signal_shutdown(struct smc_link_group *lgr);
|
|||||||
void smc_ism_get_system_eid(u8 **eid);
|
void smc_ism_get_system_eid(u8 **eid);
|
||||||
u16 smc_ism_get_chid(struct smcd_dev *dev);
|
u16 smc_ism_get_chid(struct smcd_dev *dev);
|
||||||
bool smc_ism_is_v2_capable(void);
|
bool smc_ism_is_v2_capable(void);
|
||||||
void smc_ism_init(void);
|
int smc_ism_init(void);
|
||||||
|
void smc_ism_exit(void);
|
||||||
int smcd_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);
|
int smcd_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);
|
||||||
|
|
||||||
static inline int smc_ism_write(struct smcd_dev *smcd, u64 dmb_tok,
|
static inline int smc_ism_write(struct smcd_dev *smcd, u64 dmb_tok,
|
||||||
|
|||||||
Reference in New Issue
Block a user