#include "dibs_loopback.h"
+static const char dibs_lo_dev_name[] = "lo";
/* global loopback device */
static struct dibs_lo_dev *lo_dev;
.get_fabric_id = dibs_lo_get_fabric_id,
};
-static void dibs_lo_dev_exit(struct dibs_lo_dev *ldev)
-{
- dibs_dev_del(ldev->dibs);
-}
-
static int dibs_lo_dev_probe(void)
{
struct dibs_lo_dev *ldev;
dibs->drv_priv = ldev;
dibs->ops = &dibs_lo_ops;
+ dibs->dev.parent = NULL;
+ dev_set_name(&dibs->dev, "%s", dibs_lo_dev_name);
+
ret = dibs_dev_add(dibs);
if (ret)
goto err_reg;
err_reg:
/* pairs with dibs_dev_alloc() */
- kfree(dibs);
+ put_device(&dibs->dev);
kfree(ldev);
return ret;
if (!lo_dev)
return;
- dibs_lo_dev_exit(lo_dev);
+ dibs_dev_del(lo_dev->dibs);
/* pairs with dibs_dev_alloc() */
- kfree(lo_dev->dibs);
+ put_device(&lo_dev->dibs->dev);
kfree(lo_dev);
lo_dev = NULL;
}
}
EXPORT_SYMBOL_GPL(dibs_unregister_client);
+static void dibs_dev_release(struct device *dev)
+{
+ struct dibs_dev *dibs;
+
+ dibs = container_of(dev, struct dibs_dev, dev);
+
+ kfree(dibs);
+}
+
struct dibs_dev *dibs_dev_alloc(void)
{
struct dibs_dev *dibs;
dibs = kzalloc(sizeof(*dibs), GFP_KERNEL);
+ if (!dibs)
+ return dibs;
+ dibs->dev.release = dibs_dev_release;
+ device_initialize(&dibs->dev);
return dibs;
}
int dibs_dev_add(struct dibs_dev *dibs)
{
- int i;
+ int i, ret;
+
+ ret = device_add(&dibs->dev);
+ if (ret)
+ return ret;
mutex_lock(&dibs_dev_list.mutex);
mutex_lock(&clients_lock);
mutex_unlock(&clients_lock);
list_del_init(&dibs->list);
mutex_unlock(&dibs_dev_list.mutex);
+
+ device_del(&dibs->dev);
}
EXPORT_SYMBOL_GPL(dibs_dev_del);
return ret;
}
-static void ism_dev_release(struct device *dev)
-{
- struct ism_dev *ism;
-
- ism = container_of(dev, struct ism_dev, dev);
-
- kfree(ism);
-}
-
static void ism_dev_exit(struct ism_dev *ism)
{
struct pci_dev *pdev = ism->pdev;
spin_lock_init(&ism->cmd_lock);
dev_set_drvdata(&pdev->dev, ism);
ism->pdev = pdev;
- ism->dev.parent = &pdev->dev;
- ism->dev.release = ism_dev_release;
- device_initialize(&ism->dev);
- dev_set_name(&ism->dev, "%s", dev_name(&pdev->dev));
- ret = device_add(&ism->dev);
- if (ret)
- goto err_dev;
ret = pci_enable_device_mem(pdev);
if (ret)
- goto err;
+ goto err_dev;
ret = pci_request_mem_regions(pdev, DRV_NAME);
if (ret)
if (ret)
goto err_dibs;
+ dibs->dev.parent = &pdev->dev;
+ dev_set_name(&dibs->dev, "%s", dev_name(&pdev->dev));
+
ret = dibs_dev_add(dibs);
if (ret)
goto err_ism;
ism_dev_exit(ism);
err_dibs:
/* pairs with dibs_dev_alloc() */
- kfree(dibs);
+ put_device(&dibs->dev);
err_resource:
pci_release_mem_regions(pdev);
err_disable:
pci_disable_device(pdev);
-err:
- device_del(&ism->dev);
err_dev:
dev_set_drvdata(&pdev->dev, NULL);
- put_device(&ism->dev);
+ kfree(ism);
return ret;
}
dibs_dev_del(dibs);
ism_dev_exit(ism);
/* pairs with dibs_dev_alloc() */
- kfree(dibs);
+ put_device(&dibs->dev);
pci_release_mem_regions(pdev);
pci_disable_device(pdev);
- device_del(&ism->dev);
dev_set_drvdata(&pdev->dev, NULL);
- put_device(&ism->dev);
+ kfree(ism);
}
static struct pci_driver ism_driver = {
smcd_gid->gid_ext = 0;
}
-static inline struct device *smcd_get_dev(struct smcd_dev *dev)
-{
- struct ism_dev *ism = dev->priv;
-
- return &ism->dev;
-}
-
static const struct smcd_ops ism_smcd_ops = {
.query_remote_gid = smcd_query_rgid,
.register_dmb = smcd_register_dmb,
.move_data = smcd_move,
.supports_v2 = smcd_supports_v2,
.get_local_gid = smcd_get_local_gid,
- .get_dev = smcd_get_dev,
};
const struct smcd_ops *ism_get_smcd_ops(void)
struct dibs_dev {
struct list_head list;
+ struct device dev;
/* To be filled by device driver, before calling dibs_dev_add(): */
const struct dibs_dev_ops *ops;
/* priv pointer for device driver */
struct ism_eq *ieq;
dma_addr_t ieq_dma_addr;
- struct device dev;
u64 local_gid;
int ieq_idx;
unsigned int size);
int (*supports_v2)(void);
void (*get_local_gid)(struct smcd_dev *dev, struct smcd_gid *gid);
- struct device* (*get_dev)(struct smcd_dev *dev);
/* optional operations */
int (*add_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
if (ini->is_smcd) {
/* SMC-D specific settings */
smcd = ini->ism_dev[ini->ism_selected];
- get_device(smcd->ops->get_dev(smcd));
+ get_device(&smcd->dibs->dev);
lgr->peer_gid.gid =
ini->ism_peer_gid[ini->ism_selected].gid;
lgr->peer_gid.gid_ext =
destroy_workqueue(lgr->tx_wq);
if (lgr->is_smcd) {
smc_ism_put_vlan(lgr->smcd, lgr->vlan_id);
- put_device(lgr->smcd->ops->get_dev(lgr->smcd));
+ put_device(&lgr->smcd->dibs->dev);
}
smc_lgr_put(lgr); /* theoretically last lgr_put */
}
char smc_pnet[SMC_MAX_PNETID_LEN + 1];
struct smc_pci_dev smc_pci_dev;
struct nlattr *port_attrs;
+ struct dibs_dev *dibs;
struct nlattr *attrs;
- struct ism_dev *ism;
int use_cnt = 0;
void *nlh;
- ism = smcd->priv;
+ dibs = smcd->dibs;
nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
&smc_gen_nl_family, NLM_F_MULTI,
SMC_NETLINK_GET_DEV_SMCD);
if (nla_put_u8(skb, SMC_NLA_DEV_IS_CRIT, use_cnt > 0))
goto errattr;
memset(&smc_pci_dev, 0, sizeof(smc_pci_dev));
- smc_set_pci_values(ism->pdev, &smc_pci_dev);
+ smc_set_pci_values(to_pci_dev(dibs->dev.parent), &smc_pci_dev);
if (nla_put_u32(skb, SMC_NLA_DEV_PCI_FID, smc_pci_dev.pci_fid))
goto errattr;
if (nla_put_u16(skb, SMC_NLA_DEV_PCI_CHID, smc_pci_dev.pci_pchid))
if (smc_ism_is_loopback(dibs)) {
ops = smc_lo_get_smcd_ops();
- smcd = smcd_alloc_dev(dev_name(&smc_lo->dev), ops,
+ smcd = smcd_alloc_dev(dev_name(&dibs->dev), ops,
SMC_LO_MAX_DMBS);
} else {
ism = dibs->drv_priv;
#if IS_ENABLED(CONFIG_ISM)
ops = ism_get_smcd_ops();
#endif
- smcd = smcd_alloc_dev(dev_name(&ism->pdev->dev), ops,
+ smcd = smcd_alloc_dev(dev_name(&dibs->dev), ops,
ISM_NR_DMBS);
}
if (!smcd)
ism_set_priv(ism, &smc_ism_client, smcd);
smcd->client = &smc_ism_client;
#endif
- if (smc_pnetid_by_dev_port(&ism->pdev->dev, 0, smcd->pnetid))
- smc_pnetid_by_table_smcd(smcd);
}
+ if (smc_pnetid_by_dev_port(dibs->dev.parent, 0, smcd->pnetid))
+ smc_pnetid_by_table_smcd(smcd);
+
if (smc_ism_is_loopback(dibs) || smcd->ops->supports_v2())
smc_ism_set_v2_capable();
mutex_lock(&smcd_dev_list.mutex);
}
mutex_unlock(&smcd_dev_list.mutex);
- if (smc_ism_is_loopback(dibs)) {
- pr_warn_ratelimited("smc: adding smcd loopback device\n");
- } else {
- if (smc_pnet_is_pnetid_set(smcd->pnetid))
- pr_warn_ratelimited("smc: adding smcd device %s with pnetid %.16s%s\n",
- dev_name(&ism->dev), smcd->pnetid,
- smcd->pnetid_by_user ?
- " (user defined)" :
- "");
- else
- pr_warn_ratelimited("smc: adding smcd device %s without pnetid\n",
- dev_name(&ism->dev));
- }
+ if (smc_pnet_is_pnetid_set(smcd->pnetid))
+ pr_warn_ratelimited("smc: adding smcd device %s with pnetid %.16s%s\n",
+ dev_name(&dibs->dev), smcd->pnetid,
+ smcd->pnetid_by_user ?
+ " (user defined)" :
+ "");
+ else
+ pr_warn_ratelimited("smc: adding smcd device %s without pnetid\n",
+ dev_name(&dibs->dev));
return;
}
static void smcd_unregister_dev(struct dibs_dev *dibs)
{
struct smcd_dev *smcd = dibs_get_priv(dibs, &smc_dibs_client);
- struct ism_dev *ism = dibs->drv_priv;
- if (smc_ism_is_loopback(dibs)) {
- pr_warn_ratelimited("smc: removing smcd loopback device\n");
- } else {
- pr_warn_ratelimited("smc: removing smcd device %s\n",
- dev_name(&ism->dev));
- }
+ pr_warn_ratelimited("smc: removing smcd device %s\n",
+ dev_name(&dibs->dev));
smcd->going_away = 1;
smc_smcd_terminate_all(smcd);
mutex_lock(&smcd_dev_list.mutex);
#define SMC_LO_SUPPORT_NOCOPY 0x1
#define SMC_DMA_ADDR_INVALID (~(dma_addr_t)0)
-static const char smc_lo_dev_name[] = "loopback-ism";
static struct smc_lo_dev *lo_dev;
static void smc_lo_generate_ids(struct smc_lo_dev *ldev)
smcd_gid->gid_ext = ldev->local_gid.gid_ext;
}
-static struct device *smc_lo_get_dev(struct smcd_dev *smcd)
-{
- return &((struct smc_lo_dev *)smcd->priv)->dev;
-}
-
static const struct smcd_ops lo_ops = {
.query_remote_gid = smc_lo_query_rgid,
.register_dmb = smc_lo_register_dmb,
.signal_event = NULL,
.move_data = smc_lo_move_data,
.get_local_gid = smc_lo_get_local_gid,
- .get_dev = smc_lo_get_dev,
};
const struct smcd_ops *smc_lo_get_smcd_ops(void)
wait_event(ldev->ldev_release, !atomic_read(&ldev->dmb_cnt));
}
-static void smc_lo_dev_release(struct device *dev)
-{
- struct smc_lo_dev *ldev =
- container_of(dev, struct smc_lo_dev, dev);
-
- kfree(ldev);
-}
-
static int smc_lo_dev_probe(void)
{
struct smc_lo_dev *ldev;
if (!ldev)
return -ENOMEM;
- ldev->dev.parent = NULL;
- ldev->dev.release = smc_lo_dev_release;
- device_initialize(&ldev->dev);
- dev_set_name(&ldev->dev, smc_lo_dev_name);
smc_lo_dev_init(ldev);
lo_dev = ldev; /* global loopback device */
return;
smc_lo_dev_exit(lo_dev);
- put_device(&lo_dev->dev); /* device_initialize in smc_lo_dev_probe */
+ kfree(lo_dev);
lo_dev = NULL;
}
struct smc_lo_dev {
struct smcd_dev *smcd;
- struct device dev;
struct smcd_gid local_gid;
atomic_t dmb_cnt;
rwlock_t dmb_ht_lock;
pr_warn_ratelimited("smc: smcd device %s "
"erased user defined pnetid "
"%.16s\n",
- dev_name(smcd->ops->get_dev(smcd)),
+ dev_name(&smcd->dibs->dev),
smcd->pnetid);
memset(smcd->pnetid, 0, SMC_MAX_PNETID_LEN);
smcd->pnetid_by_user = false;
mutex_lock(&smcd_dev_list.mutex);
list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
- if (!strncmp(dev_name(smcd_dev->ops->get_dev(smcd_dev)),
+ if (!strncmp(dev_name(&smcd_dev->dibs->dev),
smcd_name, IB_DEVICE_NAME_MAX - 1))
goto out;
}
bool smcddev_applied = true;
bool ibdev_applied = true;
struct smcd_dev *smcd;
- struct device *dev;
bool new_ibdev;
/* try to apply the pnetid to active devices */
if (smcd) {
smcddev_applied = smc_pnet_apply_smcd(smcd, pnet_name);
if (smcddev_applied) {
- dev = smcd->ops->get_dev(smcd);
- pr_warn_ratelimited("smc: smcd device %s "
- "applied user defined pnetid "
- "%.16s\n", dev_name(dev),
+ pr_warn_ratelimited("smc: smcd device %s applied user defined pnetid %.16s\n",
+ dev_name(&smcd->dibs->dev),
smcd->pnetid);
}
}
*/
int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
{
- const char *ib_name = dev_name(smcddev->ops->get_dev(smcddev));
+ const char *ib_name = dev_name(&smcddev->dibs->dev);
struct smc_pnettable *pnettable;
struct smc_pnetentry *tmp_pe;
struct smc_net *sn;