lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <002d7a88-84ed-4f84-be51-f0bf957b903d@yunsilicon.com>
Date: Thu, 6 Mar 2025 10:48:24 +0800
From: "Xin Tian" <tianx@...silicon.com>
To: "Kalesh Anakkur Purayil" <kalesh-anakkur.purayil@...adcom.com>
Cc: <netdev@...r.kernel.org>, <leon@...nel.org>, <andrew+netdev@...n.ch>, 
	<kuba@...nel.org>, <pabeni@...hat.com>, <edumazet@...gle.com>, 
	<davem@...emloft.net>, <jeff.johnson@....qualcomm.com>, 
	<przemyslaw.kitszel@...el.com>, <weihg@...silicon.com>, 
	<wanry@...silicon.com>, <jacky@...silicon.com>, <horms@...nel.org>, 
	<parthiban.veerasooran@...rochip.com>, <masahiroy@...nel.org>
Subject: Re: [PATCH net-next v7 01/14] xsc: Add xsc driver basic framework

On 2025/3/5 16:55, Kalesh Anakkur Purayil wrote:
> On Fri, Feb 28, 2025 at 9:12 PM Xin Tian <tianx@...silicon.com> wrote:
>> 1. Add yunsilicon xsc driver basic compile framework, including
>> xsc_pci driver and xsc_eth driver
>> 2. Implemented PCI device initialization.
>>
>> Co-developed-by: Honggang Wei <weihg@...silicon.com>
>> Signed-off-by: Honggang Wei <weihg@...silicon.com>
>> Co-developed-by: Lei Yan <jacky@...silicon.com>
>> Signed-off-by: Lei Yan <jacky@...silicon.com>
>> Signed-off-by: Xin Tian <tianx@...silicon.com>
>> ---
>>   MAINTAINERS                                   |   7 +
>>   drivers/net/ethernet/Kconfig                  |   1 +
>>   drivers/net/ethernet/Makefile                 |   1 +
>>   drivers/net/ethernet/yunsilicon/Kconfig       |  26 ++
>>   drivers/net/ethernet/yunsilicon/Makefile      |   8 +
>>   .../ethernet/yunsilicon/xsc/common/xsc_core.h |  53 ++++
>>   .../net/ethernet/yunsilicon/xsc/net/Kconfig   |  17 ++
>>   .../net/ethernet/yunsilicon/xsc/net/Makefile  |   9 +
>>   .../net/ethernet/yunsilicon/xsc/pci/Kconfig   |  16 ++
>>   .../net/ethernet/yunsilicon/xsc/pci/Makefile  |   9 +
>>   .../net/ethernet/yunsilicon/xsc/pci/main.c    | 255 ++++++++++++++++++
>>   11 files changed, 402 insertions(+)
>>   create mode 100644 drivers/net/ethernet/yunsilicon/Kconfig
>>   create mode 100644 drivers/net/ethernet/yunsilicon/Makefile
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/net/Kconfig
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/net/Makefile
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/Kconfig
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
>>   create mode 100644 drivers/net/ethernet/yunsilicon/xsc/pci/main.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index cc40a9d9b..4892dd63e 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -25285,6 +25285,13 @@ S:     Maintained
>>   F:     Documentation/input/devices/yealink.rst
>>   F:     drivers/input/misc/yealink.*
>>
>> +YUNSILICON XSC DRIVERS
>> +M:     Honggang Wei <weihg@...silicon.com>
>> +M:     Xin Tian <tianx@...silicon.com>
>> +L:     netdev@...r.kernel.org
>> +S:     Maintained
>> +F:     drivers/net/ethernet/yunsilicon/xsc
>> +
>>   Z3FOLD COMPRESSED PAGE ALLOCATOR
>>   M:     Vitaly Wool <vitaly.wool@...sulko.com>
>>   R:     Miaohe Lin <linmiaohe@...wei.com>
>> diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
>> index 0baac25db..aa6016597 100644
>> --- a/drivers/net/ethernet/Kconfig
>> +++ b/drivers/net/ethernet/Kconfig
>> @@ -82,6 +82,7 @@ source "drivers/net/ethernet/i825xx/Kconfig"
>>   source "drivers/net/ethernet/ibm/Kconfig"
>>   source "drivers/net/ethernet/intel/Kconfig"
>>   source "drivers/net/ethernet/xscale/Kconfig"
>> +source "drivers/net/ethernet/yunsilicon/Kconfig"
>>
>>   config JME
>>          tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
>> diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
>> index c03203439..c16c34d4b 100644
>> --- a/drivers/net/ethernet/Makefile
>> +++ b/drivers/net/ethernet/Makefile
>> @@ -51,6 +51,7 @@ obj-$(CONFIG_NET_VENDOR_INTEL) += intel/
>>   obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/
>>   obj-$(CONFIG_NET_VENDOR_MICROSOFT) += microsoft/
>>   obj-$(CONFIG_NET_VENDOR_XSCALE) += xscale/
>> +obj-$(CONFIG_NET_VENDOR_YUNSILICON) += yunsilicon/
>>   obj-$(CONFIG_JME) += jme.o
>>   obj-$(CONFIG_KORINA) += korina.o
>>   obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
>> diff --git a/drivers/net/ethernet/yunsilicon/Kconfig b/drivers/net/ethernet/yunsilicon/Kconfig
>> new file mode 100644
>> index 000000000..ff57fedf8
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/Kconfig
>> @@ -0,0 +1,26 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +# Yunsilicon driver configuration
>> +#
>> +
>> +config NET_VENDOR_YUNSILICON
>> +       bool "Yunsilicon devices"
>> +       default y
>> +       depends on PCI
>> +       depends on ARM64 || X86_64
>> +       help
>> +         If you have a network (Ethernet) device belonging to this class,
>> +         say Y.
>> +
>> +         Note that the answer to this question doesn't directly affect the
>> +         kernel: saying N will just cause the configurator to skip all
>> +         the questions about Yunsilicon cards. If you say Y, you will be asked
>> +         for your specific card in the following questions.
>> +
>> +if NET_VENDOR_YUNSILICON
>> +
>> +source "drivers/net/ethernet/yunsilicon/xsc/net/Kconfig"
>> +source "drivers/net/ethernet/yunsilicon/xsc/pci/Kconfig"
>> +
>> +endif # NET_VENDOR_YUNSILICON
>> diff --git a/drivers/net/ethernet/yunsilicon/Makefile b/drivers/net/ethernet/yunsilicon/Makefile
>> new file mode 100644
>> index 000000000..6fc8259a7
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/Makefile
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +# Makefile for the Yunsilicon device drivers.
>> +#
>> +
>> +# obj-$(CONFIG_YUNSILICON_XSC_ETH) += xsc/net/
>> +obj-$(CONFIG_YUNSILICON_XSC_PCI) += xsc/pci/
>> \ No newline at end of file
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
>> new file mode 100644
>> index 000000000..6627a176a
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h
>> @@ -0,0 +1,53 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> + * All rights reserved.
>> + */
>> +
>> +#ifndef __XSC_CORE_H
>> +#define __XSC_CORE_H
>> +
>> +#include <linux/pci.h>
>> +
>> +#define XSC_PCI_VENDOR_ID              0x1f67
>> +
>> +#define XSC_MC_PF_DEV_ID               0x1011
>> +#define XSC_MC_VF_DEV_ID               0x1012
>> +#define XSC_MC_PF_DEV_ID_DIAMOND       0x1021
>> +
>> +#define XSC_MF_HOST_PF_DEV_ID          0x1051
>> +#define XSC_MF_HOST_VF_DEV_ID          0x1052
>> +#define XSC_MF_SOC_PF_DEV_ID           0x1053
>> +
>> +#define XSC_MS_PF_DEV_ID               0x1111
>> +#define XSC_MS_VF_DEV_ID               0x1112
>> +
>> +#define XSC_MV_HOST_PF_DEV_ID          0x1151
>> +#define XSC_MV_HOST_VF_DEV_ID          0x1152
>> +#define XSC_MV_SOC_PF_DEV_ID           0x1153
>> +
>> +struct xsc_dev_resource {
>> +       /* protect buffer allocation according to numa node */
>> +       struct mutex            alloc_mutex;
>> +};
>> +
>> +enum xsc_pci_state {
>> +       XSC_PCI_STATE_DISABLED,
>> +       XSC_PCI_STATE_ENABLED,
>> +};
>> +
>> +struct xsc_core_device {
>> +       struct pci_dev          *pdev;
>> +       struct device           *device;
>> +       struct xsc_dev_resource *dev_res;
>> +       int                     numa_node;
>> +
>> +       void __iomem            *bar;
>> +       int                     bar_num;
>> +
>> +       struct mutex            pci_state_mutex;        /* protect pci_state */
>> +       enum xsc_pci_state      pci_state;
>> +       struct mutex            intf_state_mutex;       /* protect intf_state */
>> +       unsigned long           intf_state;
>> +};
>> +
>> +#endif
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/Kconfig b/drivers/net/ethernet/yunsilicon/xsc/net/Kconfig
>> new file mode 100644
>> index 000000000..de743487e
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/net/Kconfig
>> @@ -0,0 +1,17 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +# Yunsilicon driver configuration
>> +#
>> +
>> +config YUNSILICON_XSC_ETH
>> +       tristate "Yunsilicon XSC ethernet driver"
>> +       default n
>> +       depends on YUNSILICON_XSC_PCI
>> +       depends on NET
>> +       help
>> +         This driver provides ethernet support for
>> +         Yunsilicon XSC devices.
>> +
>> +         To compile this driver as a module, choose M here. The module
>> +         will be called xsc_eth.
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/net/Makefile b/drivers/net/ethernet/yunsilicon/xsc/net/Makefile
>> new file mode 100644
>> index 000000000..2811433af
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/net/Makefile
>> @@ -0,0 +1,9 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +
>> +ccflags-y += -I$(srctree)/drivers/net/ethernet/yunsilicon/xsc
>> +
>> +obj-$(CONFIG_YUNSILICON_XSC_ETH) += xsc_eth.o
>> +
>> +xsc_eth-y := main.o
>> \ No newline at end of file
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/Kconfig b/drivers/net/ethernet/yunsilicon/xsc/pci/Kconfig
>> new file mode 100644
>> index 000000000..2b6d79905
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/Kconfig
>> @@ -0,0 +1,16 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +# Yunsilicon PCI configuration
>> +#
>> +
>> +config YUNSILICON_XSC_PCI
>> +       tristate "Yunsilicon XSC PCI driver"
>> +       default n
>> +       select PAGE_POOL
>> +       help
>> +         This driver is common for Yunsilicon XSC
>> +         ethernet and RDMA drivers.
>> +
>> +         To compile this driver as a module, choose M here. The module
>> +         will be called xsc_pci.
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile b/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
>> new file mode 100644
>> index 000000000..709270df8
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/Makefile
>> @@ -0,0 +1,9 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> +# All rights reserved.
>> +
>> +ccflags-y += -I$(srctree)/drivers/net/ethernet/yunsilicon/xsc
>> +
>> +obj-$(CONFIG_YUNSILICON_XSC_PCI) += xsc_pci.o
>> +
>> +xsc_pci-y := main.o
>> diff --git a/drivers/net/ethernet/yunsilicon/xsc/pci/main.c b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c
>> new file mode 100644
>> index 000000000..ec3181a8e
>> --- /dev/null
>> +++ b/drivers/net/ethernet/yunsilicon/xsc/pci/main.c
>> @@ -0,0 +1,255 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Copyright (C) 2021-2025, Shanghai Yunsilicon Technology Co., Ltd.
>> + * All rights reserved.
>> + */
>> +
>> +#include "common/xsc_core.h"
>> +
>> +static const struct pci_device_id xsc_pci_id_table[] = {
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MC_PF_DEV_ID) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MC_PF_DEV_ID_DIAMOND) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MF_HOST_PF_DEV_ID) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MF_SOC_PF_DEV_ID) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MS_PF_DEV_ID) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MV_HOST_PF_DEV_ID) },
>> +       { PCI_DEVICE(XSC_PCI_VENDOR_ID, XSC_MV_SOC_PF_DEV_ID) },
>> +       { 0 }
>> +};
>> +
>> +static int set_dma_caps(struct pci_dev *pdev)
>> +{
>> +       int err;
>> +
>> +       err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
>> +       if (err)
>> +               err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>> +       else
>> +               err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
> You can simplify this as:
>
>          err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>          if (err)
>                  err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));

Thanks, Kalesh

Jakub also raised a comment here suggesting that it can be simplified to

|err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |

There's no need to fall back to a 32-bit mask now. You can see the 
reason here:

https://lkml.org/lkml/2021/6/7/227

>> +
>> +       if (!err)
>> +               dma_set_max_seg_size(&pdev->dev, SZ_2G);
>> +
>> +       return err;
>> +}
>> +
>> +static int xsc_pci_enable_device(struct xsc_core_device *xdev)
>> +{
>> +       struct pci_dev *pdev = xdev->pdev;
>> +       int err = 0;
>> +
>> +       mutex_lock(&xdev->pci_state_mutex);
>> +       if (xdev->pci_state == XSC_PCI_STATE_DISABLED) {
> Why is this pci_state checking needed. any reason to not use
> pci_is_enabled(dev)?

This is just a personal habit.

I agree that it's somewhat redundant here, and using pci_is_enabled

is enough and clearer.

I'll change the code accordingly.

>> +               err = pci_enable_device(pdev);
>> +               if (!err)
>> +                       xdev->pci_state = XSC_PCI_STATE_ENABLED;
>> +       }
>> +       mutex_unlock(&xdev->pci_state_mutex);
>> +
>> +       return err;
>> +}
>> +
>> +static void xsc_pci_disable_device(struct xsc_core_device *xdev)
>> +{
>> +       struct pci_dev *pdev = xdev->pdev;
>> +
>> +       mutex_lock(&xdev->pci_state_mutex);
>> +       if (xdev->pci_state == XSC_PCI_STATE_ENABLED) {
>> +               pci_disable_device(pdev);
>> +               xdev->pci_state = XSC_PCI_STATE_DISABLED;
>> +       }
>> +       mutex_unlock(&xdev->pci_state_mutex);
>> +}
>> +
>> +static int xsc_pci_init(struct xsc_core_device *xdev,
>> +                       const struct pci_device_id *id)
>> +{
>> +       struct pci_dev *pdev = xdev->pdev;
>> +       void __iomem *bar_base;
>> +       int bar_num = 0;
>> +       int err;
>> +
>> +       xdev->numa_node = dev_to_node(&pdev->dev);
>> +
>> +       err = xsc_pci_enable_device(xdev);
>> +       if (err) {
>> +               pci_err(pdev, "failed to enable PCI device: err=%d\n", err);
>> +               goto err_ret;
> You can return directly from here
Yes, will change
>> +       }
>> +
>> +       err = pci_request_region(pdev, bar_num, KBUILD_MODNAME);
>> +       if (err) {
>> +               pci_err(pdev, "failed to request %s pci_region=%d: err=%d\n",
>> +                       KBUILD_MODNAME, bar_num, err);
>> +               goto err_disable;
>> +       }
>> +
>> +       pci_set_master(pdev);
>> +
>> +       err = set_dma_caps(pdev);
>> +       if (err) {
>> +               pci_err(pdev, "failed to set DMA capabilities mask: err=%d\n",
>> +                       err);
>> +               goto err_clr_master;
>> +       }
>> +
>> +       bar_base = pci_ioremap_bar(pdev, bar_num);
>> +       if (!bar_base) {
>> +               pci_err(pdev, "failed to ioremap %s bar%d\n", KBUILD_MODNAME,
>> +                       bar_num);
>> +               err = -ENOMEM;
>> +               goto err_clr_master;
>> +       }
>> +
>> +       err = pci_save_state(pdev);
>> +       if (err) {
>> +               pci_err(pdev, "pci_save_state failed: err=%d\n", err);
>> +               goto err_io_unmap;
>> +       }
>> +
>> +       xdev->bar_num = bar_num;
>> +       xdev->bar = bar_base;
>> +
>> +       return 0;
>> +
>> +err_io_unmap:
>> +       pci_iounmap(pdev, bar_base);
>> +err_clr_master:
>> +       pci_clear_master(pdev);
>> +       pci_release_region(pdev, bar_num);
>> +err_disable:
>> +       xsc_pci_disable_device(xdev);
>> +err_ret:
>> +       return err;
>> +}
>> +
>> +static void xsc_pci_fini(struct xsc_core_device *xdev)
>> +{
>> +       struct pci_dev *pdev = xdev->pdev;
>> +
>> +       if (xdev->bar)
> Is this check really needed?
no need, will drop it.
>> +               pci_iounmap(pdev, xdev->bar);
>> +       pci_clear_master(pdev);
>> +       pci_release_region(pdev, xdev->bar_num);
>> +       xsc_pci_disable_device(xdev);
>> +}
>> +
>> +static int xsc_dev_res_init(struct xsc_core_device *xdev)
>> +{
>> +       struct xsc_dev_resource *dev_res;
>> +
>> +       dev_res = kvzalloc(sizeof(*dev_res), GFP_KERNEL);
>> +       if (!dev_res)
>> +               return -ENOMEM;
>> +
>> +       xdev->dev_res = dev_res;
>> +       mutex_init(&dev_res->alloc_mutex);
>> +
>> +       return 0;
>> +}
>> +
>> +static void xsc_dev_res_cleanup(struct xsc_core_device *xdev)
>> +{
>> +       kfree(xdev->dev_res);
>> +}
>> +
>> +static int xsc_core_dev_init(struct xsc_core_device *xdev)
>> +{
>> +       int err;
>> +
>> +       mutex_init(&xdev->pci_state_mutex);
>> +       mutex_init(&xdev->intf_state_mutex);
>> +
>> +       err = xsc_dev_res_init(xdev);
>> +       if (err) {
>> +               pci_err(xdev->pdev, "xsc dev res init failed %d\n", err);
>> +               goto out;
> You can avoid this label by doing "return err" instead of "return 0"
> the line below

The code is added to maintain structure with additions of next patch. ( 
same for the latter two)

Since you feel it not suitable, I'll remove  and add it where needed.

Thanks

>> +       }
>> +
>> +       return 0;
>> +out:
>> +       return err;
>> +}
>> +
>> +static void xsc_core_dev_cleanup(struct xsc_core_device *xdev)
>> +{
>> +       xsc_dev_res_cleanup(xdev);
>> +}
>> +
>> +static int xsc_pci_probe(struct pci_dev *pci_dev,
>> +                        const struct pci_device_id *id)
>> +{
>> +       struct xsc_core_device *xdev;
>> +       int err;
>> +
>> +       xdev = kzalloc(sizeof(*xdev), GFP_KERNEL);
>> +       if (!xdev)
>> +               return -ENOMEM;
>> +
>> +       xdev->pdev = pci_dev;
>> +       xdev->device = &pci_dev->dev;
>> +
>> +       pci_set_drvdata(pci_dev, xdev);
>> +       err = xsc_pci_init(xdev, id);
>> +       if (err) {
>> +               pci_err(pci_dev, "xsc_pci_init failed %d\n", err);
>> +               goto err_unset_pci_drvdata;
>> +       }
>> +
>> +       err = xsc_core_dev_init(xdev);
>> +       if (err) {
>> +               pci_err(pci_dev, "xsc_core_dev_init failed %d\n", err);
>> +               goto err_pci_fini;
>> +       }
>> +
>> +       return 0;
>> +err_pci_fini:
>> +       xsc_pci_fini(xdev);
>> +err_unset_pci_drvdata:
>> +       pci_set_drvdata(pci_dev, NULL);
>> +       kfree(xdev);
>> +
>> +       return err;
>> +}
>> +
>> +static void xsc_pci_remove(struct pci_dev *pci_dev)
>> +{
>> +       struct xsc_core_device *xdev = pci_get_drvdata(pci_dev);
>> +
>> +       xsc_core_dev_cleanup(xdev);
>> +       xsc_pci_fini(xdev);
>> +       pci_set_drvdata(pci_dev, NULL);
>> +       kfree(xdev);
>> +}
>> +
>> +static struct pci_driver xsc_pci_driver = {
>> +       .name           = "xsc-pci",
>> +       .id_table       = xsc_pci_id_table,
>> +       .probe          = xsc_pci_probe,
>> +       .remove         = xsc_pci_remove,
>> +};
>> +
>> +static int __init xsc_init(void)
>> +{
>> +       int err;
>> +
>> +       err = pci_register_driver(&xsc_pci_driver);
>> +       if (err) {
>> +               pr_err("failed to register pci driver\n");
>> +               goto out;
> There is no need of this label
>> +       }
>> +       return 0;
> "return err" here
>> +
>> +out:
>> +       return err;
>> +}
>> +
>> +static void __exit xsc_fini(void)
>> +{
>> +       pci_unregister_driver(&xsc_pci_driver);
>> +}
>> +
>> +module_init(xsc_init);
>> +module_exit(xsc_fini);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_DESCRIPTION("Yunsilicon XSC PCI driver");
>> --
>> 2.18.4
>>
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ