Re: [bug report] staging: qlge: Initialize devlink health dump framework
On Wed, Feb 03, 2021 at 05:36:01PM +0300, Dan Carpenter wrote: On Wed, Feb 03, 2021 at 09:45:51PM +0800, Coiby Xu wrote: Hi Dan, On Wed, Feb 03, 2021 at 12:42:50PM +0300, Dan Carpenter wrote: > Hello Coiby Xu, > > The patch 953b94009377: "staging: qlge: Initialize devlink health > dump framework" from Jan 23, 2021, leads to the following static > checker warning: > >drivers/staging/qlge/qlge_devlink.c:163 qlge_health_create_reporters() >error: uninitialized symbol 'reporter'. > > drivers/staging/qlge/qlge_devlink.c > 151 void qlge_health_create_reporters(struct qlge_adapter *priv) > 152 { > 153 struct devlink_health_reporter *reporter; > 154 struct devlink *devlink; > 155 > 156 devlink = priv_to_devlink(priv); > 157 priv->reporter = > 158 devlink_health_reporter_create(devlink, _reporter_ops, > 159 0, priv); > 160 if (IS_ERR(priv->reporter)) > 161 netdev_warn(priv->ndev, > 162 "Failed to create reporter, err = %ld\n", > 163 PTR_ERR(reporter)); > > Obviously the static checker is correct because we initialized > "priv->reporter" instead of "reporter". > > It's not clear to me how "reporter" is used. Presumably this should be: > >reporter = devlink_health_reporter_create(devlink, _reporter_ops, > 0, priv); >if (IS_ERR(reporter)) { >netdev_warn(priv->ndev, >"Failed to create reporter, err = %ld\n", >PTR_ERR(reporter)); >return; >} >priv->reporter = reporter; > Thank you for finding this issue! "struct devlink_health_reporter *reporter" is not needed since priv->reporter is used instead which I think simplifies the code. > But I can't actually find where "priv->reporter" is checked against > NULL. There should be some NULL checks, right? > There is no need to do NULL check since devlink_health_reporter_create has done the job for us, // net/core/devlink.c __devlink_health_reporter_create(struct devlink *devlink, const struct devlink_health_reporter_ops *ops, u64 graceful_period, void *priv) { reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); if (!reporter) return ERR_PTR(-ENOMEM); } No, Sorry I was unclear. I mean that instead of error handling this qlge_health_create_reporters() function just prints an error: netdev_warn(priv->ndev, "Failed to create reporter, err = %ld\n", PTR_ERR(priv->reporter)); Then it looks like it gets passed to qlge_reporter_coredump() which dereferences "reporter" without checking. That will crash, right? Now I see what you mean. Thanks for the explanation! I'll send a patch to address this issue. regards, dan carpenter -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH][next] staging: qlge: fix read of an uninitialized pointer
On Wed, Feb 03, 2021 at 01:38:34PM +, Colin King wrote: From: Colin Ian King Currently the pointer 'reporter' is not being initialized and is being read in a netdev_warn message. The pointer is not used and is redundant, fix this by removing it and replacing the reference to it with priv->reporter instead. Addresses-Coverity: ("Uninitialized pointer read") Fixes: 1053c27804df ("staging: qlge: coredump via devlink health reporter") Signed-off-by: Colin Ian King --- drivers/staging/qlge/qlge_devlink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index c6ef5163e241..86834d96cebf 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -150,7 +150,6 @@ static const struct devlink_health_reporter_ops qlge_reporter_ops = { void qlge_health_create_reporters(struct qlge_adapter *priv) { - struct devlink_health_reporter *reporter; struct devlink *devlink; devlink = priv_to_devlink(priv); @@ -160,5 +159,5 @@ void qlge_health_create_reporters(struct qlge_adapter *priv) if (IS_ERR(priv->reporter)) netdev_warn(priv->ndev, "Failed to create reporter, err = %ld\n", - PTR_ERR(reporter)); + PTR_ERR(priv->reporter)); } -- 2.29.2 Thanks for fixing this issue. Reviewed-by: Coiby Xu -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [bug report] staging: qlge: Initialize devlink health dump framework
Hi Dan, On Wed, Feb 03, 2021 at 12:42:50PM +0300, Dan Carpenter wrote: Hello Coiby Xu, The patch 953b94009377: "staging: qlge: Initialize devlink health dump framework" from Jan 23, 2021, leads to the following static checker warning: drivers/staging/qlge/qlge_devlink.c:163 qlge_health_create_reporters() error: uninitialized symbol 'reporter'. drivers/staging/qlge/qlge_devlink.c 151 void qlge_health_create_reporters(struct qlge_adapter *priv) 152 { 153 struct devlink_health_reporter *reporter; 154 struct devlink *devlink; 155 156 devlink = priv_to_devlink(priv); 157 priv->reporter = 158 devlink_health_reporter_create(devlink, _reporter_ops, 159 0, priv); 160 if (IS_ERR(priv->reporter)) 161 netdev_warn(priv->ndev, 162 "Failed to create reporter, err = %ld\n", 163 PTR_ERR(reporter)); Obviously the static checker is correct because we initialized "priv->reporter" instead of "reporter". It's not clear to me how "reporter" is used. Presumably this should be: reporter = devlink_health_reporter_create(devlink, _reporter_ops, 0, priv); if (IS_ERR(reporter)) { netdev_warn(priv->ndev, "Failed to create reporter, err = %ld\n", PTR_ERR(reporter)); return; } priv->reporter = reporter; Thank you for finding this issue! "struct devlink_health_reporter *reporter" is not needed since priv->reporter is used instead which I think simplifies the code. But I can't actually find where "priv->reporter" is checked against NULL. There should be some NULL checks, right? There is no need to do NULL check since devlink_health_reporter_create has done the job for us, // net/core/devlink.c __devlink_health_reporter_create(struct devlink *devlink, const struct devlink_health_reporter_ops *ops, u64 graceful_period, void *priv) { reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); if (!reporter) return ERR_PTR(-ENOMEM); } 164 } regards, dan carpenter -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4 6/8] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer
devlink health could be used to get coredump. No need to send so much data to the kernel ring buffer. Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 2 -- drivers/staging/qlge/qlge.h | 3 --- drivers/staging/qlge/qlge_dbg.c | 11 --- drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 2 -- drivers/staging/qlge/qlge_mpi.c | 6 -- 6 files changed, 25 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index 5ac55664c3e2..e68c95f47754 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -18,8 +18,6 @@ of questionable value. In particular, qlge_dbg.c has hundreds of lines of code bitrotting away in ifdef land (doesn't compile since commit 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). -* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending - on some module parameters. * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 41f69751d34d..aa5721862140 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2153,7 +2153,6 @@ struct qlge_adapter { u32 port_init; u32 link_status; struct qlge_mpi_coredump *mpi_coredump; - u32 core_is_dumped; u32 link_config; u32 led_config; u32 max_frame_size; @@ -2166,7 +2165,6 @@ struct qlge_adapter { struct delayed_work mpi_work; struct delayed_work mpi_port_cfg_work; struct delayed_work mpi_idc_work; - struct delayed_work mpi_core_to_log; struct completion ide_completion; const struct nic_operations *nic_ops; u16 device_id; @@ -2257,7 +2255,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, int size, u32 bit, void qlge_queue_fw_error(struct qlge_adapter *qdev); void qlge_mpi_work(struct work_struct *work); void qlge_mpi_reset_work(struct work_struct *work); -void qlge_mpi_core_to_log(struct work_struct *work); int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit); void qlge_queue_asic_error(struct qlge_adapter *qdev); void qlge_set_ethtool_ops(struct net_device *ndev); diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index b0d4ea071f32..5c64d6de3b30 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff) } } -/* Coredump to messages log file using separate worker thread */ -void qlge_mpi_core_to_log(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_core_to_log.work); - - print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n", - DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump, - sizeof(*qdev->mpi_coredump), false); -} - #ifdef QL_REG_DUMP static void qlge_dump_intr_states(struct qlge_adapter *qdev) { diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index 24b079523d5c..3e911f147dfc 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev, struct qlge_adapter *qdev = netdev_to_qdev(ndev); qlge_get_dump(qdev, p); - qdev->core_is_dumped = 0; if (!test_bit(QL_FRC_COREDUMP, >flags)) regs->len = sizeof(struct qlge_mpi_coredump); else diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 2ec688d3d946..747dbb54dde4 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3800,7 +3800,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter *qdev) cancel_delayed_work_sync(>mpi_reset_work); cancel_delayed_work_sync(>mpi_work); cancel_delayed_work_sync(>mpi_idc_work); - cancel_delayed_work_sync(>mpi_core_to_log); cancel_delayed_work_sync(>mpi_port_cfg_work); } @@ -4493,7 +4492,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work); INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work); INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work); - INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log); init_completion(>ide_completion); mutex_init(>mpi_mutex); diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 2b77995ec76c..2630ebf50341 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -
[PATCH v4 5/8] staging: qlge: support force_coredump option for devlink health dump
With force_coredump module parameter set, devlink health dump will reset the MPI RISC first which takes 5 secs to be finished. Note that only NIC function that owns the firmware can do the force_dumping. Otherwise devlink will receive an EPERM error. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index bf7d75ed5eae..c6ef5163e241 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -56,10 +56,23 @@ static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); struct qlge_mpi_coredump *dump; + wait_queue_head_t wait; if (!netif_running(qdev->ndev)) return 0; + if (test_bit(QL_FRC_COREDUMP, >flags)) { + if (qlge_own_firmware(qdev)) { + qlge_queue_fw_error(qdev); + init_waitqueue_head(); + wait_event_timeout(wait, 0, 5 * HZ); + } else { + netif_err(qdev, ifup, qdev->ndev, + "Force Coredump failed because this NIC function doesn't own the firmware\n"); + return -EPERM; + } + } + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); if (!dump) return -ENOMEM; -- 2.29.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4 8/8] staging: qlge: add documentation for debugging qlge
Instructions and examples on kernel data structures dumping and coredump. Signed-off-by: Coiby Xu --- .../networking/device_drivers/index.rst | 1 + .../device_drivers/qlogic/index.rst | 18 +++ .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS | 6 + 4 files changed, 143 insertions(+) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index a3113ffd7a16..d8279de7bf25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,6 +15,7 @@ Contents: ethernet/index fddi/index hamradio/index + qlogic/index wan/index wifi/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst new file mode 100644 index ..ad05b04286e4 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/index.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +QLogic QLGE Device Drivers +=== + +Contents: + +.. toctree:: + :maxdepth: 2 + + qlge + +.. only:: subproject and html + + Indices + === + + * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst new file mode 100644 index ..0b888253d152 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/qlge.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=== +QLogic QLGE 10Gb Ethernet device driver +=== + +This driver use drgn and devlink for debugging. + +Dump kernel data structures in drgn +--- + +To dump kernel data structures, the following Python script can be used +in drgn: + +.. code-block:: python + + def align(x, a): + """the alignment a should be a power of 2 + """ + mask = a - 1 + return (x+ mask) & ~mask + + def struct_size(struct_type): + struct_str = "struct {}".format(struct_type) + return sizeof(Object(prog, struct_str, address=0x0)) + + def netdev_priv(netdevice): + NETDEV_ALIGN = 32 + return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) + + name = 'xxx' + qlge_device = None + netdevices = prog['init_net'].dev_base_head.address_of_() + for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): + if netdevice.name.string_().decode('ascii') == name: + print(netdevice.name) + + ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) + +The struct ql_adapter will be printed in drgn as follows, + +>>> ql_adapter +(struct ql_adapter){ +.ricb = (struct ricb){ +.base_cq = (u8)0, +.flags = (u8)120, +.mask = (__le16)26637, +.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, +.ipv6_hash_key = (__le32 [10]){}, +.ipv4_hash_key = (__le32 [4]){}, +}, +.flags = (unsigned long)0, +.wol = (u32)0, +.nic_stats = (struct nic_stats){ +.tx_pkts = (u64)0, +.tx_bytes = (u64)0, +.tx_mcast_pkts = (u64)0, +.tx_bcast_pkts = (u64)0, +.tx_ucast_pkts = (u64)0, +.tx_ctl_pkts = (u64)0, +.tx_pause_pkts = (u64)0, +... +}, +.active_vlans = (unsigned long [64]){ +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, +18446619461681283072, 0, 42949673024, 2147483647, +}, +.rx_ring = (struct rx_ring [17]){ +{ +.cqicb = (struct cqicb){ +.msix_vect = (u8)0, +.reserved1 = (u8)0, +.reserved2 = (u8)0, +.flags = (u8)0, +.len = (__le16)0, +.rid = (__le16)0, +... +}, +
[PATCH v4 7/8] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
The debugging code in the following ifdef land - QL_ALL_DUMP - QL_REG_DUMP - QL_DEV_DUMP - QL_CB_DUMP - QL_IB_DUMP - QL_OB_DUMP becomes unnecessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Link: https://lkml.org/lkml/2020/6/30/19 Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 4 - drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 688 drivers/staging/qlge/qlge_ethtool.c | 2 - drivers/staging/qlge/qlge_main.c| 7 +- 5 files changed, 1 insertion(+), 782 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index e68c95f47754..c76394b9451b 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -14,10 +14,6 @@ queues" is confusing. * struct rx_ring is used for rx and tx completions, with some members relevant to one case only -* there is an inordinate amount of disparate debugging code, most of which is - of questionable value. In particular, qlge_dbg.c has hundreds of lines of - code bitrotting away in ifdef land (doesn't compile since commit - 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index aa5721862140..55e0ad759250 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2289,86 +2289,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, struct sk_buff *skb); int qlge_own_firmware(struct qlge_adapter *qdev); int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); -/* #define QL_ALL_DUMP */ -/* #define QL_REG_DUMP */ -/* #define QL_DEV_DUMP */ -/* #define QL_CB_DUMP */ -/* #define QL_IB_DUMP */ -/* #define QL_OB_DUMP */ - -#ifdef QL_REG_DUMP -void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev); -void qlge_dump_routing_entries(struct qlge_adapter *qdev); -void qlge_dump_regs(struct qlge_adapter *qdev); -#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev) -#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev) -#else -#define QL_DUMP_REGS(qdev) -#define QL_DUMP_ROUTE(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) -#endif - -#ifdef QL_STAT_DUMP -void qlge_dump_stat(struct qlge_adapter *qdev); -#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev) -#else -#define QL_DUMP_STAT(qdev) -#endif - -#ifdef QL_DEV_DUMP -void qlge_dump_qdev(struct qlge_adapter *qdev); -#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev) -#else -#define QL_DUMP_QDEV(qdev) -#endif - -#ifdef QL_CB_DUMP -void qlge_dump_wqicb(struct wqicb *wqicb); -void qlge_dump_tx_ring(struct tx_ring *tx_ring); -void qlge_dump_ricb(struct ricb *ricb); -void qlge_dump_cqicb(struct cqicb *cqicb); -void qlge_dump_rx_ring(struct rx_ring *rx_ring); -void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ - qlge_dump_hw_cb(qdev, size, bit, q_id) -#else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) -#endif - -#ifdef QL_OB_DUMP -void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd); -void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct qlge_ob_mac_iocb_req *ob_mac_iocb); -void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct qlge_ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, ob_mac_rsp) -#else -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) -#endif - -#ifdef QL_IB_DUMP -void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct qlge_ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, ib_mac_rsp) -#else -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) -#endif - -#ifdef QL_ALL_DUMP -void qlge_dump_all(struct qlge_adapter *qdev); -#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev) -#else -#define QL_DUMP_ALL(qdev) -#endif - #endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/q
[PATCH v4 4/8] staging: qlge: coredump via devlink health reporter
$ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 132 ++-- 1 file changed, 126 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index d9c71f45211f..bf7d75ed5eae 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -2,16 +2,136 @@ #include "qlge.h" #include "qlge_devlink.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int qlge_fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int regs_num = (seg_header->seg_size + - sizeof(struct mpi_coredump_segment_header)) / sizeof(u32); + int err; + int i; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define FILL_SEG(seg_hdr, seg_regs)\ + do {\ + err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err; \ + } \ + } while (0) + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); + struct qlge_mpi_coredump *dump; + + if (!netif_running(qdev->ndev)) + return 0; + + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); + if (!dump) + return -ENOMEM; + + err = qlge_core_dump(qdev, dump); + if (err) { + kvfree(dump); + return err; + } + + qlge_soft_reset_mpi_risc(qdev); + + FILL_SEG(core_regs_seg_hdr, mpi_core_regs); + FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs); + FILL_SEG(rmii_regs_seg_hdr, rmii_regs); + FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs); + FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs); + FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); + FILL_SEG(ide_regs_seg_hdr, ide_regs); + FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); + FILL_SEG(smbus_regs_seg_hdr, smbus_regs); + FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); + FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); + FILL_SEG(i2c_regs_seg_hdr, i2c_regs); + FILL_SEG(memc_regs_seg_hdr, memc_regs); + FILL_SEG(pbus_regs_seg_hdr, pbus_regs)
[PATCH v4 3/8] staging: qlge: re-write qlge_init_device
Stop calling ql_release_all in qlge_init_device and free things one step at a time. struct qlge_adapter *qdev is now a private structure of struct devlink and memset is not necessary. Link: https://lore.kernel.org/patchwork/patch/1321092/#1516928 Suggested-by: Dan Carpenter Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 32 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index bb9fc590d97b..2ec688d3d946 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -4394,13 +4394,13 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, err = pcie_set_readrq(pdev, 4096); if (err) { dev_err(>dev, "Set readrq failed.\n"); - goto err_out1; + goto err_disable_pci; } err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(>dev, "PCI region request failed.\n"); - return err; + goto err_disable_pci; } pci_set_master(pdev); @@ -4416,7 +4416,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (err) { dev_err(>dev, "No usable DMA configuration.\n"); - goto err_out2; + goto err_release_pci; } /* Set PCIe reset type for EEH to fundamental. */ @@ -4427,7 +4427,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (!qdev->reg_base) { dev_err(>dev, "Register mapping failed.\n"); err = -ENOMEM; - goto err_out2; + goto err_release_pci; } qdev->doorbell_area_size = pci_resource_len(pdev, 3); @@ -4436,14 +4436,14 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (!qdev->doorbell_area) { dev_err(>dev, "Doorbell register mapping failed.\n"); err = -ENOMEM; - goto err_out2; + goto err_iounmap_base; } err = qlge_get_board_info(qdev); if (err) { dev_err(>dev, "Register access failed.\n"); err = -EIO; - goto err_out2; + goto err_iounmap_doorbell; } qdev->msg_enable = netif_msg_init(debug, default_msg); spin_lock_init(>stats_lock); @@ -4453,7 +4453,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, vmalloc(sizeof(struct qlge_mpi_coredump)); if (!qdev->mpi_coredump) { err = -ENOMEM; - goto err_out2; + goto err_iounmap_doorbell; } if (qlge_force_coredump) set_bit(QL_FRC_COREDUMP, >flags); @@ -4462,7 +4462,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, err = qdev->nic_ops->get_flash(qdev); if (err) { dev_err(>dev, "Invalid FLASH.\n"); - goto err_out2; + goto err_free_mpi_coredump; } /* Keep local copy of current mac address. */ @@ -4485,7 +4485,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, ndev->name); if (!qdev->workqueue) { err = -ENOMEM; - goto err_out2; + goto err_free_mpi_coredump; } INIT_DELAYED_WORK(>asic_reset_work, qlge_asic_reset_work); @@ -4503,10 +4503,18 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, DRV_NAME, DRV_VERSION); } return 0; -err_out2: - qlge_release_all(pdev); -err_out1: + +err_free_mpi_coredump: + vfree(qdev->mpi_coredump); +err_iounmap_doorbell: + iounmap(qdev->doorbell_area); +err_iounmap_base: + iounmap(qdev->reg_base); +err_release_pci: + pci_release_regions(pdev); +err_disable_pci: pci_disable_device(pdev); + return err; } -- 2.29.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4 2/8] staging: qlge: Initialize devlink health dump framework
Initialize devlink health dump framework for the qlge driver so the coredump could be done via devlink. struct qlge_adapter is now used as the private data structure of struct devlink so it could exist independently of struct net_device and devlink reload could be supported in the future. The private data of PCIe driver now points to qlge_adapter. Since devlink_alloc will zero out struct qlge_adapter, memset in qlge_init_device is not necessary. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 13 +++ drivers/staging/qlge/qlge_devlink.c | 31 +++ drivers/staging/qlge/qlge_devlink.h | 9 ++ drivers/staging/qlge/qlge_ethtool.c | 36 drivers/staging/qlge/qlge_main.c| 125 +--- 7 files changed, 151 insertions(+), 66 deletions(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 1ac85f2f770f..41f69751d34d 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,18 @@ struct nic_operations { int (*port_initialize)(struct qlge_adapter *qdev); }; +struct qlge_netdev_priv { + struct qlge_adapter *qdev; + struct net_device *ndev; +}; + +static inline +struct qlge_adapter *netdev_to_qdev(struct net_device *ndev) +{ + struct qlge_netdev_priv *ndev_priv = netdev_priv(ndev); + + return ndev_priv->qdev; +} /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2077,6 +2089,7 @@ struct qlge_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct devlink_health_reporter *reporter; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c new file mode 100644 index ..d9c71f45211f --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "qlge.h" +#include "qlge_devlink.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; + +void qlge_health_create_reporters(struct qlge_adapter *priv) +{ + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + priv->reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, priv); + if (IS_ERR(priv->reporter)) + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); +} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h new file mode 100644 index ..19078e1ac694 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef QLGE_DEVLINK_H +#define QLGE_DEVLINK_H + +#include + +void qlge_health_create_reporters(struct qlge_adapter *priv); + +#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index 3e577e1bc27c..24b079523d5c 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -366,7 +366,7 @@ static void qlge_get_ethtool_stats(struct net_device *ndev, struct ethtool_stats *stats, u64 *data) { - struct qlge_adapter *qdev = netdev_priv(ndev); + struct qlge_adapter *qdev = netdev_to_qdev(ndev); int index, length; length = QLGE_STATS_LEN; @@ -3
[PATCH v4 0/8] staging: qlge: Re-writing the debugging features
This patch set aims to avoid dumping registers, data structures and coredump to dmesg and also to reduce the code size of the qlge driver. As pointed out by Benjamin [1], > At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet > drivers. Most of what it does is dump kernel data structures or pci > memory mapped registers to dmesg. There are better facilities for that. > My thinking is not simply to delete qlge_dbg.c but to replace it, making > sure that most of the same information is still available. For data > structures, crash or drgn can be used; possibly with a script for the > latter which formats the data. For pci registers, they should be > included in the ethtool register dump and a patch added to ethtool to > pretty print them. That's what other drivers like e1000e do. For the > "coredump", devlink health can be used. So the debugging features are re-written following Benjamin's advice, - dump kernel data structures in drgn - use devlink to do coredump which also includes device status and general registers For the usage examples of supported devlink commands, please check the last patch. The tests have been done successfully following Shung-Hsi's steps[2] on a machine from Red Hat, - build the kernel and this driver with KASAN, UBSAN, DEBUG_ATOMIC_SLEEP, PROVE_LOCKING and DEBUG_KMEMLEAK enabled - load and unload the driver - devlink health dump [1] https://lkml.org/lkml/2020/6/30/19 [2] https://lore.kernel.org/netdev/20200816025717.GA28176@f3/T/ v3 -> v4 - remove unnecessary memeset in qlge_init_device [Shung-Hsi Yu] - Call qlge_soft_reset_mpi_risc after getting coredump - only allow force_coredump for NIC function that owns the firmware v2 -> v3 - Fix newly introduced resource leak [Dan Carpenter] - Fix bugs after using struct qlge_adapter as the private data struct of devlink - Add qlge_ prefix for structures not having a prefix and fix a left-over ql_adapter [Benjamin Poirier] v1 -> v2 - Call devlink_free when register_netdev fails [Willem de Bruijn] - "scripts/checkpatch.pl --strict" for changes [Dan Carpente] - Declares variables in "Reverse Christmas Tree" [Dan Carpente] - Use the sizeof() directly [Dan Carpente] - Add SPDX-License-Identifier to qlge_devlink.{c,h} - Rename ql_* to qlge_* [Benjamin Poirier] - Update drivers/staging/qlge/TODO [Benjamin Poirier] - struct qlge_adapter is now used as the private data struct of devlink instead of net_device [Benjamin Poirier] RFC -> v1 - select NET_DEVLINK in Kconfig [Benjamin Poirier] - Don't do a coredump when the interface is down [Shung-Hsi Yu] - Remove stray newlines [Benjamin Poirier] - force_coredump for devlink - Remove mpi_core_to_log which will output the coredump to the kernel ring buffer - Put drgn script under Documentation [Benjamin Poirier] - Rename qlge_health.* to qlge_devlink.* Coiby Xu (8): staging: qlge: use qlge_* prefix to avoid namespace clashes with other qlogic drivers staging: qlge: Initialize devlink health dump framework staging: qlge: re-write qlge_init_device staging: qlge: coredump via devlink health reporter staging: qlge: support force_coredump option for devlink health dump staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land staging: qlge: add documentation for debugging qlge .../networking/device_drivers/index.rst |1 + .../device_drivers/qlogic/index.rst | 18 + .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS |6 + drivers/staging/qlge/Kconfig |1 + drivers/staging/qlge/Makefile |2 +- drivers/staging/qlge/TODO | 10 - drivers/staging/qlge/qlge.h | 244 +-- drivers/staging/qlge/qlge_dbg.c | 1650 + drivers/staging/qlge/qlge_devlink.c | 164 ++ drivers/staging/qlge/qlge_devlink.h |9 + drivers/staging/qlge/qlge_ethtool.c | 233 ++- drivers/staging/qlge/qlge_main.c | 1376 +++--- drivers/staging/qlge/qlge_mpi.c | 356 ++-- 14 files changed, 1873 insertions(+), 2315 deletions(-) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h -- 2.29.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3 2/8] staging: qlge: Initialize devlink health dump framework
Hi, Thank you for testing this patch! On Tue, Oct 20, 2020 at 06:27:41PM +0800, Shung-Hsi Yu wrote: On Tue, Oct 20, 2020 at 04:57:11PM +0800, Shung-Hsi Yu wrote: Hi, This patch trigger the following KASAN error inside qlge_init_device(). [...] general protection fault, probably for non-canonical address 0xdc4b: [#1] SMP DEBUG_PAGEALLOC KASAN PTI [...] KASAN: null-ptr-deref in range [0x0258-0x025f] [...] CPU: 0 PID: 438 Comm: systemd-udevd Tainted: G C E 5.9.0-kvmsmall+ #7 [...] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-48- g...ilt.opensuse.org 04/01/2014 [...] RIP: 0010:qlge_get_8000_flash_params+0x377/0x6e0 [qlge] [...] Code: 03 80 3c 02 00 0f 85 57 03 00 00 49 8b af 68 08 00 00 48 b8 00 00 00 00 00 fc ff df 48 8d bd 5f 02 00 00 48 89 fa 48 c1 ea 03 <0f> b6 04 02 48 89 fa 83 e2 07 38 d0 7f 08 84 c0 0f 85 c6 02 00 00 [...] RSP: 0018:c9f97788 EFLAGS: 00010207 [...] RAX: dc00 RBX: RCX: [...] RDX: 004b RSI: c08cb843 RDI: 025f [...] R10: fbfff5f718a0 R11: 0001 R12: dc00 [...] R13: 888111085d40 R14: 888111085d40 R15: 888111080280 [...] FS: 7f315f5db280() GS:8881f520() knlGS: [...] CS: 0010 DS: ES: CR0: 80050033 [...] CR2: 55bb25297170 CR3: 000110674000 CR4: 06f0 [...] DR0: DR1: DR2: [...] DR3: DR6: fffe0ff0 DR7: 0400 [...] Call Trace: [...] ? qlge_get_8012_flash_params+0x600/0x600 [qlge] [...] ? static_obj+0x8a/0xc0 [...] ? lockdep_init_map_waits+0x26a/0x700 [...] qlge_init_device+0x425/0x1000 [qlge] [...] ? debug_mutex_init+0x31/0x60 [...] qlge_probe+0xfe/0x6c0 [qlge] With qlge_get_8000_flash_params+0x377/0x6e0 corresponding to the following: if (qdev->flash.flash_params_8000.data_type1 == 2) memcpy(mac_addr, qdev->flash.flash_params_8000.mac_addr1, qdev->ndev->addr_len); // < Here This is because qdev->ndev == 0. The reason is that before qlge_get_8000_flash_params() get called qdev is memset-ed inside qlge_init_device(). static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, int cards_found) { struct net_device *ndev = qdev->ndev; int err = 0; memset((void *)qdev, 0, sizeof(*qdev)); // ... // qlge_get_8000_flash_params() get's called err = qdev->nic_ops->get_flash(qdev); // ... } Thank you for reporting this issue and providing the fix. I was a bit confused after reading previous email because I dind't notice memset and the address of ((struct net_device *) 0)->addr_len is 0x026f which is outside the range reported by KASAN, [...] KASAN: null-ptr-deref in range [0x0258-0x025f] -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers
On Sun, Oct 18, 2020 at 08:02:53PM +0900, Benjamin Poirier wrote: On 2020-10-17 07:16 +0800, Coiby Xu wrote: On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote: > On 2020-10-14 18:43 +0800, Coiby Xu wrote: > > To avoid namespace clashes with other qlogic drivers and also for the > > sake of naming consistency, use the "qlge_" prefix as suggested in > > drivers/staging/qlge/TODO. > > > > Suggested-by: Benjamin Poirier > > Signed-off-by: Coiby Xu > > --- > > drivers/staging/qlge/TODO |4 - > > drivers/staging/qlge/qlge.h | 190 ++-- > > drivers/staging/qlge/qlge_dbg.c | 1073 --- > > drivers/staging/qlge/qlge_ethtool.c | 231 ++--- > > drivers/staging/qlge/qlge_main.c| 1257 +-- > > drivers/staging/qlge/qlge_mpi.c | 352 > > 6 files changed, 1551 insertions(+), 1556 deletions(-) > > > > diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO > > index f93f7428f5d5..5ac55664c3e2 100644 > > --- a/drivers/staging/qlge/TODO > > +++ b/drivers/staging/qlge/TODO > > @@ -28,10 +28,6 @@ > > * the driver has a habit of using runtime checks where compile time checks are > >possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers()) > > * reorder struct members to avoid holes if it doesn't impact performance > > -* in terms of namespace, the driver uses either qlge_, ql_ (used by > > - other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with > > - clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" > > - prefix. > > You only renamed ql -> qlge. The prefix needs to be added where there is > currently none like the second example of that text. On second thoughts, these structs like ob_mac_iocb_req are defined in local headers and there is no mixed usage. So even when we want to build this diver and other qlogic drivers into the kernel instead of as separate modules, it won't lead to real problems, is it right? Using cscope or ctags and searching for ob_mac_iocb_req will yield ambiguous results. It might also make things more difficult if using a debugger. Even if I have been using gtags, I didn't realize it. Thank you for explaining it to me. Looking at other drivers (ex. ice, mlx5), they use a prefix for their private types, just like for their static functions, even though it's not absolutely necessary. I think it's helpful when reading the code because it quickly shows that it is something that was defined in the driver, not in some subsystem. Good point! I didn't think about it earlier but it would have been better to leave out this renaming to a subsequent patchset, since this change is unrelated to the debugging features. It seems it's more reasonable to do renaming first. So in a sense, the renaming is a preparatory step for the debugging features. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Thu, Oct 15, 2020 at 08:06:06PM +0900, Benjamin Poirier wrote: On 2020-10-15 11:37 +0800, Coiby Xu wrote: On Tue, Oct 13, 2020 at 09:37:04AM +0900, Benjamin Poirier wrote: > On 2020-10-12 19:24 +0800, Coiby Xu wrote: > [...] > > > I think, but didn't check in depth, that in those drivers, the devlink > > > device is tied to the pci device and can exist independently of the > > > netdev, at least in principle. > > > > > You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example, > > devlink reload would first first unregister_netdev and then > > register_netdev but struct devlink stays put. But I have yet to > > understand when unregister/register_netdev is needed. > > Maybe it can be useful to manually recover if the hardware or driver > gets in an erroneous state. I've used `modprobe -r qlge && modprobe > qlge` for the same in the past. Thank you for providing this user case! > > > Do we need to > > add "devlink reload" for qlge? > > Not for this patchset. That would be a new feature. To implement this feature, it seems I need to understand how qlge work under the hood. For example, what's the difference between qlge_soft_reset_mpi_risc and qlge_hard_reset_mpi_risc? Or should we use a brute-force way like do the tasks in qlge_remove and then re-do the tasks in qlge_probe? I don't know. Like I've said before, I'd recommend testing on actual hardware. I don't have access to it anymore. Yeah, as I'm changing more code, it's more and more important to test it on actual hardware. Have you heard anyone installing qle8142 to Raspberry Pi which has a PCIe bus. Is a hardware reference manual for qlge device? I've never gotten access to one. My experience of wrestling with an AMD GPIO chip [1] shows it would be a bit annoying to deal with a device without a reference manual. I have to treat it like a blackbox and try different kinds of input to see what would happen. Btw, it seems resetting the device is a kind of panacea. For example, according to the specs of my touchpad (Synaptics RMI4 Specification), it even has the feature of spontaneous reset. devlink health [2] also has the so-called auto-recovery. So resetting is a common phenomenon. I wonder if there are some common guidelines to do resetting which also apply to the qlge8*** devices. The only noteworthy thing from Qlogic that I know of is the firmware update: http://driverdownloads.qlogic.com/QLogicDriverDownloads_UI/SearchByProduct.aspx?ProductCategory=322=1104=190 It did fix some weird behavior when I applied it so I'd recommend doing the same if you get an adapter. Thank you for sharing the info! [1] https://www.spinics.net/lists/linux-gpio/msg53901.html [2] https://www.kernel.org/doc/html/latest/networking/devlink/devlink-health.html -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers
On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote: On 2020-10-14 18:43 +0800, Coiby Xu wrote: To avoid namespace clashes with other qlogic drivers and also for the sake of naming consistency, use the "qlge_" prefix as suggested in drivers/staging/qlge/TODO. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO |4 - drivers/staging/qlge/qlge.h | 190 ++-- drivers/staging/qlge/qlge_dbg.c | 1073 --- drivers/staging/qlge/qlge_ethtool.c | 231 ++--- drivers/staging/qlge/qlge_main.c| 1257 +-- drivers/staging/qlge/qlge_mpi.c | 352 6 files changed, 1551 insertions(+), 1556 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index f93f7428f5d5..5ac55664c3e2 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -28,10 +28,6 @@ * the driver has a habit of using runtime checks where compile time checks are possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers()) * reorder struct members to avoid holes if it doesn't impact performance -* in terms of namespace, the driver uses either qlge_, ql_ (used by - other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with - clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" - prefix. You only renamed ql -> qlge. The prefix needs to be added where there is currently none like the second example of that text. On second thoughts, these structs like ob_mac_iocb_req are defined in local headers and there is no mixed usage. So even when we want to build this diver and other qlogic drivers into the kernel instead of as separate modules, it won't lead to real problems, is it right? Besides, the next patch reintroduces the name struct ql_adapter. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 8/8] staging: qlge: add documentation for debugging qlge
Instructions and examples on kernel data structures dumping and coredump. Signed-off-by: Coiby Xu --- .../networking/device_drivers/index.rst | 1 + .../device_drivers/qlogic/index.rst | 18 +++ .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS | 6 + 4 files changed, 143 insertions(+) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index a3113ffd7a16..d8279de7bf25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,6 +15,7 @@ Contents: ethernet/index fddi/index hamradio/index + qlogic/index wan/index wifi/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst new file mode 100644 index ..ad05b04286e4 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/index.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +QLogic QLGE Device Drivers +=== + +Contents: + +.. toctree:: + :maxdepth: 2 + + qlge + +.. only:: subproject and html + + Indices + === + + * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst new file mode 100644 index ..0b888253d152 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/qlge.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=== +QLogic QLGE 10Gb Ethernet device driver +=== + +This driver use drgn and devlink for debugging. + +Dump kernel data structures in drgn +--- + +To dump kernel data structures, the following Python script can be used +in drgn: + +.. code-block:: python + + def align(x, a): + """the alignment a should be a power of 2 + """ + mask = a - 1 + return (x+ mask) & ~mask + + def struct_size(struct_type): + struct_str = "struct {}".format(struct_type) + return sizeof(Object(prog, struct_str, address=0x0)) + + def netdev_priv(netdevice): + NETDEV_ALIGN = 32 + return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) + + name = 'xxx' + qlge_device = None + netdevices = prog['init_net'].dev_base_head.address_of_() + for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): + if netdevice.name.string_().decode('ascii') == name: + print(netdevice.name) + + ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) + +The struct ql_adapter will be printed in drgn as follows, + +>>> ql_adapter +(struct ql_adapter){ +.ricb = (struct ricb){ +.base_cq = (u8)0, +.flags = (u8)120, +.mask = (__le16)26637, +.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, +.ipv6_hash_key = (__le32 [10]){}, +.ipv4_hash_key = (__le32 [4]){}, +}, +.flags = (unsigned long)0, +.wol = (u32)0, +.nic_stats = (struct nic_stats){ +.tx_pkts = (u64)0, +.tx_bytes = (u64)0, +.tx_mcast_pkts = (u64)0, +.tx_bcast_pkts = (u64)0, +.tx_ucast_pkts = (u64)0, +.tx_ctl_pkts = (u64)0, +.tx_pause_pkts = (u64)0, +... +}, +.active_vlans = (unsigned long [64]){ +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, +18446619461681283072, 0, 42949673024, 2147483647, +}, +.rx_ring = (struct rx_ring [17]){ +{ +.cqicb = (struct cqicb){ +.msix_vect = (u8)0, +.reserved1 = (u8)0, +.reserved2 = (u8)0, +.flags = (u8)0, +.len = (__le16)0, +.rid = (__le16)0, +... +}, +
[PATCH v3 7/8] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
The debugging code in the following ifdef land - QL_ALL_DUMP - QL_REG_DUMP - QL_DEV_DUMP - QL_CB_DUMP - QL_IB_DUMP - QL_OB_DUMP becomes unnecessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Link: https://lkml.org/lkml/2020/6/30/19 Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 4 - drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 688 drivers/staging/qlge/qlge_ethtool.c | 2 - drivers/staging/qlge/qlge_main.c| 7 +- 5 files changed, 1 insertion(+), 782 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index e68c95f47754..c76394b9451b 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -14,10 +14,6 @@ queues" is confusing. * struct rx_ring is used for rx and tx completions, with some members relevant to one case only -* there is an inordinate amount of disparate debugging code, most of which is - of questionable value. In particular, qlge_dbg.c has hundreds of lines of - code bitrotting away in ifdef land (doesn't compile since commit - 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 8552ca7433f5..9015e2b0b54a 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2289,86 +2289,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, struct sk_buff *skb); int qlge_own_firmware(struct qlge_adapter *qdev); int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); -/* #define QL_ALL_DUMP */ -/* #define QL_REG_DUMP */ -/* #define QL_DEV_DUMP */ -/* #define QL_CB_DUMP */ -/* #define QL_IB_DUMP */ -/* #define QL_OB_DUMP */ - -#ifdef QL_REG_DUMP -void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev); -void qlge_dump_routing_entries(struct qlge_adapter *qdev); -void qlge_dump_regs(struct qlge_adapter *qdev); -#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev) -#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev) -#else -#define QL_DUMP_REGS(qdev) -#define QL_DUMP_ROUTE(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) -#endif - -#ifdef QL_STAT_DUMP -void qlge_dump_stat(struct qlge_adapter *qdev); -#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev) -#else -#define QL_DUMP_STAT(qdev) -#endif - -#ifdef QL_DEV_DUMP -void qlge_dump_qdev(struct qlge_adapter *qdev); -#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev) -#else -#define QL_DUMP_QDEV(qdev) -#endif - -#ifdef QL_CB_DUMP -void qlge_dump_wqicb(struct wqicb *wqicb); -void qlge_dump_tx_ring(struct tx_ring *tx_ring); -void qlge_dump_ricb(struct ricb *ricb); -void qlge_dump_cqicb(struct cqicb *cqicb); -void qlge_dump_rx_ring(struct rx_ring *rx_ring); -void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ - qlge_dump_hw_cb(qdev, size, bit, q_id) -#else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) -#endif - -#ifdef QL_OB_DUMP -void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd); -void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct qlge_ob_mac_iocb_req *ob_mac_iocb); -void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct qlge_ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, ob_mac_rsp) -#else -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) -#endif - -#ifdef QL_IB_DUMP -void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct qlge_ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, ib_mac_rsp) -#else -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) -#endif - -#ifdef QL_ALL_DUMP -void qlge_dump_all(struct qlge_adapter *qdev); -#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev) -#else -#define QL_DUMP_ALL(qdev) -#endif - #endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/q
[PATCH v3 6/8] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer
devlink health could be used to get coredump. No need to send so much data to the kernel ring buffer. Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 2 -- drivers/staging/qlge/qlge.h | 3 --- drivers/staging/qlge/qlge_dbg.c | 11 --- drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 2 -- drivers/staging/qlge/qlge_mpi.c | 6 -- 6 files changed, 25 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index 5ac55664c3e2..e68c95f47754 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -18,8 +18,6 @@ of questionable value. In particular, qlge_dbg.c has hundreds of lines of code bitrotting away in ifdef land (doesn't compile since commit 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). -* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending - on some module parameters. * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 0a470f02b0c6..8552ca7433f5 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2153,7 +2153,6 @@ struct qlge_adapter { u32 port_init; u32 link_status; struct qlge_mpi_coredump *mpi_coredump; - u32 core_is_dumped; u32 link_config; u32 led_config; u32 max_frame_size; @@ -2166,7 +2165,6 @@ struct qlge_adapter { struct delayed_work mpi_work; struct delayed_work mpi_port_cfg_work; struct delayed_work mpi_idc_work; - struct delayed_work mpi_core_to_log; struct completion ide_completion; const struct nic_operations *nic_ops; u16 device_id; @@ -2257,7 +2255,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, int size, u32 bit, void qlge_queue_fw_error(struct qlge_adapter *qdev); void qlge_mpi_work(struct work_struct *work); void qlge_mpi_reset_work(struct work_struct *work); -void qlge_mpi_core_to_log(struct work_struct *work); int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit); void qlge_queue_asic_error(struct qlge_adapter *qdev); void qlge_set_ethtool_ops(struct net_device *ndev); diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index b0d4ea071f32..5c64d6de3b30 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff) } } -/* Coredump to messages log file using separate worker thread */ -void qlge_mpi_core_to_log(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_core_to_log.work); - - print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n", - DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump, - sizeof(*qdev->mpi_coredump), false); -} - #ifdef QL_REG_DUMP static void qlge_dump_intr_states(struct qlge_adapter *qdev) { diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index 24b079523d5c..3e911f147dfc 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev, struct qlge_adapter *qdev = netdev_to_qdev(ndev); qlge_get_dump(qdev, p); - qdev->core_is_dumped = 0; if (!test_bit(QL_FRC_COREDUMP, >flags)) regs->len = sizeof(struct qlge_mpi_coredump); else diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index c081aa1bb43d..b138109a24a5 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3808,7 +3808,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter *qdev) cancel_delayed_work_sync(>mpi_reset_work); cancel_delayed_work_sync(>mpi_work); cancel_delayed_work_sync(>mpi_idc_work); - cancel_delayed_work_sync(>mpi_core_to_log); cancel_delayed_work_sync(>mpi_port_cfg_work); } @@ -4502,7 +4501,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work); INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work); INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work); - INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log); init_completion(>ide_completion); mutex_init(>mpi_mutex); diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index e67d2f8652a3..7dd9e2de30e5 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -
[PATCH v3 5/8] staging: qlge: support force_coredump option for devlink health dump
With force_coredump module parameter set, devlink health dump will reset the MPI RISC first which takes 5 secs to be finished. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index b75ec5bff26a..92db531ad5e0 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); struct qlge_mpi_coredump *dump; + wait_queue_head_t wait; if (!netif_running(qdev->ndev)) return 0; + if (test_bit(QL_FRC_COREDUMP, >flags)) { + qlge_queue_fw_error(qdev); + init_waitqueue_head(); + wait_event_timeout(wait, 0, 5 * HZ); + } + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); if (!dump) return -ENOMEM; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 4/8] staging: qlge: coredump via devlink health reporter
$ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 130 ++-- 1 file changed, 124 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index d9c71f45211f..b75ec5bff26a 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -2,16 +2,134 @@ #include "qlge.h" #include "qlge_devlink.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int qlge_fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int regs_num = (seg_header->seg_size + - sizeof(struct mpi_coredump_segment_header)) / sizeof(u32); + int err; + int i; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define FILL_SEG(seg_hdr, seg_regs)\ + do {\ + err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err; \ + } \ + } while (0) + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); + struct qlge_mpi_coredump *dump; + + if (!netif_running(qdev->ndev)) + return 0; + + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); + if (!dump) + return -ENOMEM; + + err = qlge_core_dump(qdev, dump); + if (err) { + kvfree(dump); + return err; + } + + FILL_SEG(core_regs_seg_hdr, mpi_core_regs); + FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs); + FILL_SEG(rmii_regs_seg_hdr, rmii_regs); + FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs); + FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs); + FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); + FILL_SEG(ide_regs_seg_hdr, ide_regs); + FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); + FILL_SEG(smbus_regs_seg_hdr, smbus_regs); + FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); + FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); + FILL_SEG(i2c_regs_seg_hdr, i2c_regs); + FILL_SEG(memc_regs_seg_hdr, memc_regs); + FILL_SEG(pbus_regs_seg_hdr, pbus_regs); + FILL_SEG(mde_regs_seg_hdr, mde_r
[PATCH v3 3/8] staging: qlge: re-write qlge_init_device
Stop calling ql_release_all in qlge_init_device and free things one step at a time. Link: https://lore.kernel.org/patchwork/patch/1321092/#1516928 Suggested-by: Dan Carpenter Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 32 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 888179fbf98c..c081aa1bb43d 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -4403,13 +4403,13 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, err = pcie_set_readrq(pdev, 4096); if (err) { dev_err(>dev, "Set readrq failed.\n"); - goto err_out1; + goto err_disable_pci; } err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(>dev, "PCI region request failed.\n"); - return err; + goto err_disable_pci; } pci_set_master(pdev); @@ -4425,7 +4425,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (err) { dev_err(>dev, "No usable DMA configuration.\n"); - goto err_out2; + goto err_release_pci; } /* Set PCIe reset type for EEH to fundamental. */ @@ -4436,7 +4436,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (!qdev->reg_base) { dev_err(>dev, "Register mapping failed.\n"); err = -ENOMEM; - goto err_out2; + goto err_release_pci; } qdev->doorbell_area_size = pci_resource_len(pdev, 3); @@ -4445,14 +4445,14 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, if (!qdev->doorbell_area) { dev_err(>dev, "Doorbell register mapping failed.\n"); err = -ENOMEM; - goto err_out2; + goto err_iounmap_base; } err = qlge_get_board_info(qdev); if (err) { dev_err(>dev, "Register access failed.\n"); err = -EIO; - goto err_out2; + goto err_iounmap_doorbell; } qdev->msg_enable = netif_msg_init(debug, default_msg); spin_lock_init(>stats_lock); @@ -4462,7 +4462,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, vmalloc(sizeof(struct qlge_mpi_coredump)); if (!qdev->mpi_coredump) { err = -ENOMEM; - goto err_out2; + goto err_iounmap_doorbell; } if (qlge_force_coredump) set_bit(QL_FRC_COREDUMP, >flags); @@ -4471,7 +4471,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, err = qdev->nic_ops->get_flash(qdev); if (err) { dev_err(>dev, "Invalid FLASH.\n"); - goto err_out2; + goto err_free_mpi_coredump; } /* Keep local copy of current mac address. */ @@ -4494,7 +4494,7 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, ndev->name); if (!qdev->workqueue) { err = -ENOMEM; - goto err_out2; + goto err_free_mpi_coredump; } INIT_DELAYED_WORK(>asic_reset_work, qlge_asic_reset_work); @@ -4512,10 +4512,18 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, DRV_NAME, DRV_VERSION); } return 0; -err_out2: - qlge_release_all(pdev); -err_out1: + +err_free_mpi_coredump: + vfree(qdev->mpi_coredump); +err_iounmap_doorbell: + iounmap(qdev->doorbell_area); +err_iounmap_base: + iounmap(qdev->reg_base); +err_release_pci: + pci_release_regions(pdev); +err_disable_pci: pci_disable_device(pdev); + return err; } -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 2/8] staging: qlge: Initialize devlink health dump framework
Initialize devlink health dump framework for the qlge driver so the coredump could be done via devlink. struct qlge_adapter is now used as the private data structure of struct devlink so it could exist independently of struct net_device and devlink reload could be supported in the future. The private data of PCIe driver now points to qlge_adapter. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 13 +++ drivers/staging/qlge/qlge_devlink.c | 31 +++ drivers/staging/qlge/qlge_devlink.h | 9 ++ drivers/staging/qlge/qlge_ethtool.c | 36 drivers/staging/qlge/qlge_main.c| 124 +--- 7 files changed, 151 insertions(+), 65 deletions(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 57947f9336a8..0a470f02b0c6 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,18 @@ struct nic_operations { int (*port_initialize)(struct qlge_adapter *qdev); }; +struct qlge_netdev_priv { + struct qlge_adapter *qdev; + struct net_device *ndev; +}; + +static inline +struct qlge_adapter *netdev_to_qdev(struct net_device *ndev) +{ + struct qlge_netdev_priv *ndev_priv = netdev_priv(ndev); + + return ndev_priv->qdev; +} /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2077,6 +2089,7 @@ struct qlge_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct devlink_health_reporter *reporter; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c new file mode 100644 index ..d9c71f45211f --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "qlge.h" +#include "qlge_devlink.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; + +void qlge_health_create_reporters(struct qlge_adapter *priv) +{ + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + priv->reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, priv); + if (IS_ERR(priv->reporter)) + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); +} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h new file mode 100644 index ..19078e1ac694 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef QLGE_DEVLINK_H +#define QLGE_DEVLINK_H + +#include + +void qlge_health_create_reporters(struct qlge_adapter *priv); + +#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index 3e577e1bc27c..24b079523d5c 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -366,7 +366,7 @@ static void qlge_get_ethtool_stats(struct net_device *ndev, struct ethtool_stats *stats, u64 *data) { - struct qlge_adapter *qdev = netdev_priv(ndev); + struct qlge_adapter *qdev = netdev_to_qdev(ndev); int index, length; length = QLGE_STATS_LEN; @@ -383,7 +383,7 @@ qlge_get_ethtool_stats(struct net_device *ndev, static int qlge_get_link_ksetti
[PATCH v3 0/8] staging: qlge: Re-writing the debugging features
This patch set aims to avoid dumping registers, data structures and coredump to dmesg and also to reduce the code size of the qlge driver. As pointed out by Benjamin [1], > At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet > drivers. Most of what it does is dump kernel data structures or pci > memory mapped registers to dmesg. There are better facilities for that. > My thinking is not simply to delete qlge_dbg.c but to replace it, making > sure that most of the same information is still available. For data > structures, crash or drgn can be used; possibly with a script for the > latter which formats the data. For pci registers, they should be > included in the ethtool register dump and a patch added to ethtool to > pretty print them. That's what other drivers like e1000e do. For the > "coredump", devlink health can be used. So the debugging features are re-written following Benjamin's advice, - dump kernel data structures in drgn - use devlink to do coredump which also includes device status and general registers For the usage examples of supported devlink commands, please check the last patch. [1] https://lkml.org/lkml/2020/6/30/19 v2 -> v3 - Fix newly introduced resource leak [Dan Carpenter] - Fix bugs after using struct qlge_adapter as the private data struct of devlink - Add qlge_ prefix for structures not having a prefix and fix a left-over ql_adapter [Benjamin Poirier] v1 -> v2 - Call devlink_free when register_netdev fails [Willem de Bruijn] - "scripts/checkpatch.pl --strict" for changes [Dan Carpente] - Declares variables in "Reverse Christmas Tree" [Dan Carpente] - Use the sizeof() directly [Dan Carpente] - Add SPDX-License-Identifier to qlge_devlink.{c,h} - Rename ql_* to qlge_* [Benjamin Poirier] - Update drivers/staging/qlge/TODO [Benjamin Poirier] - struct qlge_adapter is now used as the private data struct of devlink instead of net_device [Benjamin Poirier] RFC -> v1 - select NET_DEVLINK in Kconfig [Benjamin Poirier] - Don't do a coredump when the interface is down [Shung-Hsi Yu] - Remove stray newlines [Benjamin Poirier] - force_coredump for devlink - Remove mpi_core_to_log which will output the coredump to the kernel ring buffer - Put drgn script under Documentation [Benjamin Poirier] - Rename qlge_health.* to qlge_devlink.* Coiby Xu (8): staging: qlge: use qlge_* prefix to avoid namespace clashes with other qlogic drivers staging: qlge: Initialize devlink health dump framework staging: qlge: re-write qlge_init_device staging: qlge: coredump via devlink health reporter staging: qlge: support force_coredump option for devlink health dump staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land staging: qlge: add documentation for debugging qlge .../networking/device_drivers/index.rst |1 + .../device_drivers/qlogic/index.rst | 18 + .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS |6 + drivers/staging/qlge/Kconfig |1 + drivers/staging/qlge/Makefile |2 +- drivers/staging/qlge/TODO | 10 - drivers/staging/qlge/qlge.h | 244 +-- drivers/staging/qlge/qlge_dbg.c | 1650 + drivers/staging/qlge/qlge_devlink.c | 156 ++ drivers/staging/qlge/qlge_devlink.h |9 + drivers/staging/qlge/qlge_ethtool.c | 234 ++- drivers/staging/qlge/qlge_main.c | 1375 +++--- drivers/staging/qlge/qlge_mpi.c | 356 ++-- 14 files changed, 1866 insertions(+), 2314 deletions(-) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers
On Thu, Oct 15, 2020 at 12:26:28PM +0800, Coiby Xu wrote: On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote: On 2020-10-14 18:43 +0800, Coiby Xu wrote: To avoid namespace clashes with other qlogic drivers and also for the sake of naming consistency, use the "qlge_" prefix as suggested in drivers/staging/qlge/TODO. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO |4 - drivers/staging/qlge/qlge.h | 190 ++-- drivers/staging/qlge/qlge_dbg.c | 1073 --- drivers/staging/qlge/qlge_ethtool.c | 231 ++--- drivers/staging/qlge/qlge_main.c| 1257 +-- drivers/staging/qlge/qlge_mpi.c | 352 6 files changed, 1551 insertions(+), 1556 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index f93f7428f5d5..5ac55664c3e2 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -28,10 +28,6 @@ * the driver has a habit of using runtime checks where compile time checks are possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers()) * reorder struct members to avoid holes if it doesn't impact performance -* in terms of namespace, the driver uses either qlge_, ql_ (used by - other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with - clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" - prefix. You only renamed ql -> qlge. The prefix needs to be added where there is currently none like the second example of that text. Thank you for reminding me of the second example! Besides, the next patch reintroduces the name struct ql_adapter. Oh, there is still a left-over ql_adapter in qlge.h (I renamed ql->qlge after initializing the devlink framework earlier but did a git rebase to make the order of the changes more reasonable). Thank you for the reminding! Btw, is there a way to configure kernel building to let the compiler discover this kind of issue automatically? -- Best regards, Coiby -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/7] staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers
On Thu, Oct 15, 2020 at 10:01:36AM +0900, Benjamin Poirier wrote: On 2020-10-14 18:43 +0800, Coiby Xu wrote: To avoid namespace clashes with other qlogic drivers and also for the sake of naming consistency, use the "qlge_" prefix as suggested in drivers/staging/qlge/TODO. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO |4 - drivers/staging/qlge/qlge.h | 190 ++-- drivers/staging/qlge/qlge_dbg.c | 1073 --- drivers/staging/qlge/qlge_ethtool.c | 231 ++--- drivers/staging/qlge/qlge_main.c| 1257 +-- drivers/staging/qlge/qlge_mpi.c | 352 6 files changed, 1551 insertions(+), 1556 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index f93f7428f5d5..5ac55664c3e2 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -28,10 +28,6 @@ * the driver has a habit of using runtime checks where compile time checks are possible (ex. ql_free_rx_buffers(), ql_alloc_rx_buffers()) * reorder struct members to avoid holes if it doesn't impact performance -* in terms of namespace, the driver uses either qlge_, ql_ (used by - other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with - clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" - prefix. You only renamed ql -> qlge. The prefix needs to be added where there is currently none like the second example of that text. Thank you for reminding me of the second example! Besides, the next patch reintroduces the name struct ql_adapter. Oh, there is still a left-over ql_adapter in qlge.h (I renamed ql->qlge after initializing the devlink framework earlier but did a git rebase to make the order of the changes more reasonable). Thank you for the reminding! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 2/7] staging: qlge: Initialize devlink health dump framework
On Wed, Oct 14, 2020 at 04:08:46PM +0300, Dan Carpenter wrote: On Wed, Oct 14, 2020 at 06:43:01PM +0800, Coiby Xu wrote: static int qlge_probe(struct pci_dev *pdev, const struct pci_device_id *pci_entry) { struct net_device *ndev = NULL; struct qlge_adapter *qdev = NULL; + struct devlink *devlink; static int cards_found; int err = 0; - ndev = alloc_etherdev_mq(sizeof(struct qlge_adapter), + devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_adapter)); + if (!devlink) + return -ENOMEM; + + qdev = devlink_priv(devlink); + + ndev = alloc_etherdev_mq(sizeof(struct qlge_netdev_priv), min(MAX_CPUS, netif_get_num_default_rss_queues())); if (!ndev) - return -ENOMEM; + goto devlink_free; - err = qlge_init_device(pdev, ndev, cards_found); - if (err < 0) { - free_netdev(ndev); - return err; In the old code, if qlge_init_device() fails then it frees "ndev". - } + qdev->ndev = ndev; + err = qlge_init_device(pdev, qdev, cards_found); + if (err < 0) + goto devlink_free; But the patch introduces a new resource leak. Thank you for spotting this issue! - qdev = netdev_priv(ndev); SET_NETDEV_DEV(ndev, >dev); ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | @@ -4611,8 +4619,14 @@ static int qlge_probe(struct pci_dev *pdev, qlge_release_all(pdev); pci_disable_device(pdev); free_netdev(ndev); - return err; + goto devlink_free; } + + err = devlink_register(devlink, >dev); + if (err) + goto devlink_free; + + qlge_health_create_reporters(qdev); /* Start up the timer to trigger EEH if * the bus goes dead */ @@ -4623,6 +4637,10 @@ static int qlge_probe(struct pci_dev *pdev, atomic_set(>lb_count, 0); cards_found++; return 0; + +devlink_free: + devlink_free(devlink); + return err; } The best way to write error handling code is keep tracke of the most recent allocation which was allocated successfully. one = alloc(); if (!one) return -ENOMEM; // <-- nothing allocated successfully two = alloc(); if (!two) { ret = -ENOMEM; goto free_one; // <-- one was allocated successfully // Notice that the label name says what // the goto does. } three = alloc(); if (!three) { ret = -ENOMEM; goto free_two; // <-- two allocated, two freed. } ... return 0; free_two: free(two); free_one: free(one); return ret; Thank you for teaching me this pattern! In the old code qlge_probe() freed things before returning, and that's fine if there is only two allocations in the function but when there are three or more allocations, then use gotos to unwind. Ideally there would be a ql_deinit_device() function to mirror the ql_init_device() function. The ql_init_device() is staging quality code with leaks and bad label names. It should be re-written to free things one step at a time instead of calling ql_release_all(). I'll see how I can improve ql_init_device. Thank you for the suggestion! Anyway, let's not introduce new leaks at least. regards, dan carpenter -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Tue, Oct 13, 2020 at 09:37:04AM +0900, Benjamin Poirier wrote: On 2020-10-12 19:24 +0800, Coiby Xu wrote: [...] > I think, but didn't check in depth, that in those drivers, the devlink > device is tied to the pci device and can exist independently of the > netdev, at least in principle. > You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example, devlink reload would first first unregister_netdev and then register_netdev but struct devlink stays put. But I have yet to understand when unregister/register_netdev is needed. Maybe it can be useful to manually recover if the hardware or driver gets in an erroneous state. I've used `modprobe -r qlge && modprobe qlge` for the same in the past. Thank you for providing this user case! Do we need to add "devlink reload" for qlge? Not for this patchset. That would be a new feature. To implement this feature, it seems I need to understand how qlge work under the hood. For example, what's the difference between qlge_soft_reset_mpi_risc and qlge_hard_reset_mpi_risc? Or should we use a brute-force way like do the tasks in qlge_remove and then re-do the tasks in qlge_probe? Is a hardware reference manual for qlge device? -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 4/7] staging: qlge: support force_coredump option for devlink health dump
With force_coredump module parameter set, devlink health dump will reset the MPI RISC first which takes 5 secs to be finished. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index b75ec5bff26a..92db531ad5e0 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); struct qlge_mpi_coredump *dump; + wait_queue_head_t wait; if (!netif_running(qdev->ndev)) return 0; + if (test_bit(QL_FRC_COREDUMP, >flags)) { + qlge_queue_fw_error(qdev); + init_waitqueue_head(); + wait_event_timeout(wait, 0, 5 * HZ); + } + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); if (!dump) return -ENOMEM; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 6/7] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
The debugging code in the following ifdef land - QL_ALL_DUMP - QL_REG_DUMP - QL_DEV_DUMP - QL_CB_DUMP - QL_IB_DUMP - QL_OB_DUMP becomes unnecessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 4 - drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 688 drivers/staging/qlge/qlge_ethtool.c | 2 - drivers/staging/qlge/qlge_main.c| 7 +- 5 files changed, 1 insertion(+), 782 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index e68c95f47754..c76394b9451b 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -14,10 +14,6 @@ queues" is confusing. * struct rx_ring is used for rx and tx completions, with some members relevant to one case only -* there is an inordinate amount of disparate debugging code, most of which is - of questionable value. In particular, qlge_dbg.c has hundreds of lines of - code bitrotting away in ifdef land (doesn't compile since commit - 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 5eb5c9a6fb84..1a26cbc67b79 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2281,86 +2281,4 @@ void qlge_check_lb_frame(struct qlge_adapter *qdev, struct sk_buff *skb); int qlge_own_firmware(struct qlge_adapter *qdev); int qlge_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); -/* #define QL_ALL_DUMP */ -/* #define QL_REG_DUMP */ -/* #define QL_DEV_DUMP */ -/* #define QL_CB_DUMP */ -/* #define QL_IB_DUMP */ -/* #define QL_OB_DUMP */ - -#ifdef QL_REG_DUMP -void qlge_dump_xgmac_control_regs(struct qlge_adapter *qdev); -void qlge_dump_routing_entries(struct qlge_adapter *qdev); -void qlge_dump_regs(struct qlge_adapter *qdev); -#define QL_DUMP_REGS(qdev) qlge_dump_regs(qdev) -#define QL_DUMP_ROUTE(qdev) qlge_dump_routing_entries(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) qlge_dump_xgmac_control_regs(qdev) -#else -#define QL_DUMP_REGS(qdev) -#define QL_DUMP_ROUTE(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) -#endif - -#ifdef QL_STAT_DUMP -void qlge_dump_stat(struct qlge_adapter *qdev); -#define QL_DUMP_STAT(qdev) qlge_dump_stat(qdev) -#else -#define QL_DUMP_STAT(qdev) -#endif - -#ifdef QL_DEV_DUMP -void qlge_dump_qdev(struct qlge_adapter *qdev); -#define QL_DUMP_QDEV(qdev) qlge_dump_qdev(qdev) -#else -#define QL_DUMP_QDEV(qdev) -#endif - -#ifdef QL_CB_DUMP -void qlge_dump_wqicb(struct wqicb *wqicb); -void qlge_dump_tx_ring(struct tx_ring *tx_ring); -void qlge_dump_ricb(struct ricb *ricb); -void qlge_dump_cqicb(struct cqicb *cqicb); -void qlge_dump_rx_ring(struct rx_ring *rx_ring); -void qlge_dump_hw_cb(struct qlge_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) qlge_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) qlge_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) qlge_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) qlge_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) qlge_dump_rx_ring(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ - qlge_dump_hw_cb(qdev, size, bit, q_id) -#else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) -#endif - -#ifdef QL_OB_DUMP -void qlge_dump_tx_desc(struct qlge_adapter *qdev, struct tx_buf_desc *tbd); -void qlge_dump_ob_mac_iocb(struct qlge_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); -void qlge_dump_ob_mac_rsp(struct qlge_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) qlge_dump_ob_mac_iocb(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) qlge_dump_ob_mac_rsp(qdev, ob_mac_rsp) -#else -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) -#endif - -#ifdef QL_IB_DUMP -void qlge_dump_ib_mac_rsp(struct qlge_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) qlge_dump_ib_mac_rsp(qdev, ib_mac_rsp) -#else -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) -#endif - -#ifdef QL_ALL_DUMP -void qlge_dump_all(struct qlge_adapter *qdev); -#define QL_DUMP_ALL(qdev) qlge_dump_all(qdev) -#else -#define QL_DUMP_ALL(qdev) -#endif - #endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 43bc9580da9e..37e593f0fd82 100644 --- a/
[PATCH v2 5/7] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer
devlink health could be used to get coredump. No need to send so much data to the kernel ring buffer. Signed-off-by: Coiby Xu --- drivers/staging/qlge/TODO | 2 -- drivers/staging/qlge/qlge.h | 3 --- drivers/staging/qlge/qlge_dbg.c | 11 --- drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 2 -- drivers/staging/qlge/qlge_mpi.c | 6 -- 6 files changed, 25 deletions(-) diff --git a/drivers/staging/qlge/TODO b/drivers/staging/qlge/TODO index 5ac55664c3e2..e68c95f47754 100644 --- a/drivers/staging/qlge/TODO +++ b/drivers/staging/qlge/TODO @@ -18,8 +18,6 @@ of questionable value. In particular, qlge_dbg.c has hundreds of lines of code bitrotting away in ifdef land (doesn't compile since commit 18c49b91777c ("qlge: do vlan cleanup", v3.1-rc1), 8 years ago). -* triggering an ethtool regdump will hexdump a 176k struct to dmesg depending - on some module parameters. * the flow control implementation in firmware is buggy (sends a flood of pause frames, resets the link, device and driver buffer queues become desynchronized), disable it by default diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 4a48bcc88fbd..5eb5c9a6fb84 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2145,7 +2145,6 @@ struct qlge_adapter { u32 port_init; u32 link_status; struct qlge_mpi_coredump *mpi_coredump; - u32 core_is_dumped; u32 link_config; u32 led_config; u32 max_frame_size; @@ -2158,7 +2157,6 @@ struct qlge_adapter { struct delayed_work mpi_work; struct delayed_work mpi_port_cfg_work; struct delayed_work mpi_idc_work; - struct delayed_work mpi_core_to_log; struct completion ide_completion; const struct nic_operations *nic_ops; u16 device_id; @@ -2249,7 +2247,6 @@ int qlge_write_cfg(struct qlge_adapter *qdev, void *ptr, int size, u32 bit, void qlge_queue_fw_error(struct qlge_adapter *qdev); void qlge_mpi_work(struct work_struct *work); void qlge_mpi_reset_work(struct work_struct *work); -void qlge_mpi_core_to_log(struct work_struct *work); int qlge_wait_reg_rdy(struct qlge_adapter *qdev, u32 reg, u32 bit, u32 ebit); void qlge_queue_asic_error(struct qlge_adapter *qdev); void qlge_set_ethtool_ops(struct net_device *ndev); diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 3d904f15568d..43bc9580da9e 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1313,17 +1313,6 @@ void qlge_get_dump(struct qlge_adapter *qdev, void *buff) } } -/* Coredump to messages log file using separate worker thread */ -void qlge_mpi_core_to_log(struct work_struct *work) -{ - struct qlge_adapter *qdev = - container_of(work, struct qlge_adapter, mpi_core_to_log.work); - - print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n", - DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump, - sizeof(*qdev->mpi_coredump), false); -} - #ifdef QL_REG_DUMP static void qlge_dump_intr_states(struct qlge_adapter *qdev) { diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index 3e577e1bc27c..c65d58fe159b 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -617,7 +617,6 @@ static void qlge_get_regs(struct net_device *ndev, struct qlge_adapter *qdev = netdev_priv(ndev); qlge_get_dump(qdev, p); - qdev->core_is_dumped = 0; if (!test_bit(QL_FRC_COREDUMP, >flags)) regs->len = sizeof(struct qlge_mpi_coredump); else diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 7a4bae3c12d0..128dd2fa2d41 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3808,7 +3808,6 @@ static void qlge_cancel_all_work_sync(struct qlge_adapter *qdev) cancel_delayed_work_sync(>mpi_reset_work); cancel_delayed_work_sync(>mpi_work); cancel_delayed_work_sync(>mpi_idc_work); - cancel_delayed_work_sync(>mpi_core_to_log); cancel_delayed_work_sync(>mpi_port_cfg_work); } @@ -4503,7 +4502,6 @@ static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, INIT_DELAYED_WORK(>mpi_work, qlge_mpi_work); INIT_DELAYED_WORK(>mpi_port_cfg_work, qlge_mpi_port_cfg_work); INIT_DELAYED_WORK(>mpi_idc_work, qlge_mpi_idc_work); - INIT_DELAYED_WORK(>mpi_core_to_log, qlge_mpi_core_to_log); init_completion(>ide_completion); mutex_init(>mpi_mutex); diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index e67d2f8652a3..7dd9e2de30e5 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -
[PATCH v2 3/7] staging: qlge: coredump via devlink health reporter
$ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 130 ++-- 1 file changed, 124 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index d9c71f45211f..b75ec5bff26a 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -2,16 +2,134 @@ #include "qlge.h" #include "qlge_devlink.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int qlge_fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int regs_num = (seg_header->seg_size + - sizeof(struct mpi_coredump_segment_header)) / sizeof(u32); + int err; + int i; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define FILL_SEG(seg_hdr, seg_regs)\ + do {\ + err = qlge_fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err; \ + } \ + } while (0) + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); + struct qlge_mpi_coredump *dump; + + if (!netif_running(qdev->ndev)) + return 0; + + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); + if (!dump) + return -ENOMEM; + + err = qlge_core_dump(qdev, dump); + if (err) { + kvfree(dump); + return err; + } + + FILL_SEG(core_regs_seg_hdr, mpi_core_regs); + FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs); + FILL_SEG(rmii_regs_seg_hdr, rmii_regs); + FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs); + FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs); + FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); + FILL_SEG(ide_regs_seg_hdr, ide_regs); + FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); + FILL_SEG(smbus_regs_seg_hdr, smbus_regs); + FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); + FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); + FILL_SEG(i2c_regs_seg_hdr, i2c_regs); + FILL_SEG(memc_regs_seg_hdr, memc_regs); + FILL_SEG(pbus_regs_seg_hdr, pbus_regs); + FILL_SEG(mde_regs_seg_hdr, mde_r
[PATCH v2 0/7] staging: qlge: Re-writing the debugging features
This patch set aims to avoid dumping registers, data structures and coredump to dmesg and also to reduce the code size of the qlge driver. As pointed out by Benjamin [1], > At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet > drivers. Most of what it does is dump kernel data structures or pci > memory mapped registers to dmesg. There are better facilities for that. > My thinking is not simply to delete qlge_dbg.c but to replace it, making > sure that most of the same information is still available. For data > structures, crash or drgn can be used; possibly with a script for the > latter which formats the data. For pci registers, they should be > included in the ethtool register dump and a patch added to ethtool to > pretty print them. That's what other drivers like e1000e do. For the > "coredump", devlink health can be used. So the debugging features are re-written following Benjamin's advice, - dump kernel data structures in drgn - use devlink to do coredump which also includes device status and general registers [1] https://lkml.org/lkml/2020/6/30/19 v1 -> v2 - Call devlink_free when register_netdev fails [Willem de Bruijn] - "scripts/checkpatch.pl --strict" for changes [Dan Carpente] - Declares variables in "Reverse Christmas Tree" [Dan Carpente] - Use the sizeof() directly [Dan Carpente] - Add SPDX-License-Identifier to qlge_devlink.{c,h} - Rename ql_* to qlge_* [Benjamin Poirier] - Update drivers/staging/qlge/TODO [Benjamin Poirier] - struct qlge_adapter is now used as the private data struct of devlink instead of net_device [Benjamin Poirier] RFC -> v1 - select NET_DEVLINK in Kconfig [Benjamin Poirier] - Don't do a coredump when the interface is down [Shung-Hsi Yu] - Remove stray newlines [Benjamin Poirier] - force_coredump for devlink - Remove mpi_core_to_log which will output the coredump to the kernel ring buffer - Put drgn script under Documentation [Benjamin Poirier] - Rename qlge_health.* to qlge_devlink.* Coiby Xu (7): staging: qlge: replace ql_* with qlge_* to avoid namespace clashes with other qlogic drivers staging: qlge: Initialize devlink health dump framework staging: qlge: coredump via devlink health reporter staging: qlge: support force_coredump option for devlink health dump staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land staging: qlge: add documentation for debugging qlge .../networking/device_drivers/index.rst |1 + .../device_drivers/qlogic/index.rst | 18 + .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS |6 + drivers/staging/qlge/Kconfig |1 + drivers/staging/qlge/Makefile |2 +- drivers/staging/qlge/TODO | 10 - drivers/staging/qlge/qlge.h | 216 +-- drivers/staging/qlge/qlge_dbg.c | 1650 + drivers/staging/qlge/qlge_devlink.c | 156 ++ drivers/staging/qlge/qlge_devlink.h |9 + drivers/staging/qlge/qlge_ethtool.c | 234 ++- drivers/staging/qlge/qlge_main.c | 1302 ++--- drivers/staging/qlge/qlge_mpi.c | 356 ++-- 14 files changed, 1802 insertions(+), 2277 deletions(-) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 2/7] staging: qlge: Initialize devlink health dump framework
Initialize devlink health dump framework for the qlge driver so the coredump could be done via devlink. struct qlge_adapter is now used as the private data struct of struct devlink so it could exist independently of struct net_device and devlink reload could be supported in the future. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 5 +++ drivers/staging/qlge/qlge_devlink.c | 31 +++ drivers/staging/qlge/qlge_devlink.h | 9 ++ drivers/staging/qlge/qlge_main.c| 48 + 6 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 6ee83e7efd7c..4a48bcc88fbd 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,10 @@ struct nic_operations { int (*port_initialize)(struct qlge_adapter *qdev); }; +struct qlge_netdev_priv { + struct ql_adapter *qdev; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2077,6 +2081,7 @@ struct qlge_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct devlink_health_reporter *reporter; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c new file mode 100644 index ..d9c71f45211f --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include "qlge.h" +#include "qlge_devlink.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; + +void qlge_health_create_reporters(struct qlge_adapter *priv) +{ + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + priv->reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, priv); + if (IS_ERR(priv->reporter)) + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); +} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h new file mode 100644 index ..19078e1ac694 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef QLGE_DEVLINK_H +#define QLGE_DEVLINK_H + +#include + +void qlge_health_create_reporters(struct qlge_adapter *priv); + +#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 19e72279b0ce..7a4bae3c12d0 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -42,6 +42,7 @@ #include #include "qlge.h" +#include "qlge_devlink.h" char qlge_driver_name[] = DRV_NAME; const char qlge_driver_version[] = DRV_VERSION; @@ -4382,10 +4383,10 @@ static void qlge_release_all(struct pci_dev *pdev) pci_release_regions(pdev); } -static int qlge_init_device(struct pci_dev *pdev, struct net_device *ndev, +static int qlge_init_device(struct pci_dev *pdev, struct qlge_adapter *qdev, int cards_found) { - struct qlge_adapter *qdev = netdev_priv(ndev); + struct net_device *ndev = qdev->ndev; int err = 0; memset((void *)qdev, 0, sizeof(*qdev)); @@ -4548,27 +4549,34 @@ static void qlge_timer(struct timer_list *t) mod
[PATCH v2 7/7] staging: qlge: add documentation for debugging qlge
Instructions and examples on kernel data structures dumping and coredump. Signed-off-by: Coiby Xu --- .../networking/device_drivers/index.rst | 1 + .../device_drivers/qlogic/index.rst | 18 +++ .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS | 6 + 4 files changed, 143 insertions(+) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index a3113ffd7a16..d8279de7bf25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,6 +15,7 @@ Contents: ethernet/index fddi/index hamradio/index + qlogic/index wan/index wifi/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst new file mode 100644 index ..ad05b04286e4 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/index.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +QLogic QLGE Device Drivers +=== + +Contents: + +.. toctree:: + :maxdepth: 2 + + qlge + +.. only:: subproject and html + + Indices + === + + * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst new file mode 100644 index ..0b888253d152 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/qlge.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=== +QLogic QLGE 10Gb Ethernet device driver +=== + +This driver use drgn and devlink for debugging. + +Dump kernel data structures in drgn +--- + +To dump kernel data structures, the following Python script can be used +in drgn: + +.. code-block:: python + + def align(x, a): + """the alignment a should be a power of 2 + """ + mask = a - 1 + return (x+ mask) & ~mask + + def struct_size(struct_type): + struct_str = "struct {}".format(struct_type) + return sizeof(Object(prog, struct_str, address=0x0)) + + def netdev_priv(netdevice): + NETDEV_ALIGN = 32 + return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) + + name = 'xxx' + qlge_device = None + netdevices = prog['init_net'].dev_base_head.address_of_() + for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): + if netdevice.name.string_().decode('ascii') == name: + print(netdevice.name) + + ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) + +The struct ql_adapter will be printed in drgn as follows, + +>>> ql_adapter +(struct ql_adapter){ +.ricb = (struct ricb){ +.base_cq = (u8)0, +.flags = (u8)120, +.mask = (__le16)26637, +.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, +.ipv6_hash_key = (__le32 [10]){}, +.ipv4_hash_key = (__le32 [4]){}, +}, +.flags = (unsigned long)0, +.wol = (u32)0, +.nic_stats = (struct nic_stats){ +.tx_pkts = (u64)0, +.tx_bytes = (u64)0, +.tx_mcast_pkts = (u64)0, +.tx_bcast_pkts = (u64)0, +.tx_ucast_pkts = (u64)0, +.tx_ctl_pkts = (u64)0, +.tx_pause_pkts = (u64)0, +... +}, +.active_vlans = (unsigned long [64]){ +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, +18446619461681283072, 0, 42949673024, 2147483647, +}, +.rx_ring = (struct rx_ring [17]){ +{ +.cqicb = (struct cqicb){ +.msix_vect = (u8)0, +.reserved1 = (u8)0, +.reserved2 = (u8)0, +.flags = (u8)0, +.len = (__le16)0, +.rid = (__le16)0, +... +}, +
Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter
On Sat, Oct 10, 2020 at 10:22:30PM +0900, Benjamin Poirier wrote: On 2020-10-10 18:02 +0800, Coiby Xu wrote: [...] > > + do { \ > > + err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ > > + if (err) { \ > > + kvfree(dump); \ > > + return err;\ > > + } \ > > + } while (0) > > + > > +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, > > + struct devlink_fmsg *fmsg, void *priv_ctx, > > + struct netlink_ext_ack *extack) > > +{ > > + int err = 0; > > + > > + struct qlge_devlink *dev = devlink_health_reporter_priv(reporter); > > Please name this variable ql_devlink, like in qlge_probe(). I happened to find the following text in drivers/staging/qlge/TODO > * in terms of namespace, the driver uses either qlge_, ql_ (used by > other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with > clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" > prefix. This comment applies to global identifiers, not local variables. Thank you for the explanation! Are you suggesting we should choose different naming styles so we better tell global identifiers from local variables? So I will adopt qlge_ instead. Besides I prefer qlge_dl to ql_devlink. Up to you but personally, I think ql_devlink is better. In any case, "dev" is too general and often used for struct net_device pointers instead. Thank you for the suggestion. Another reason to use qlge_dl is many other network drivers supporting devlink interface also adopt this kind of style. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
On Sat, Oct 10, 2020 at 10:40:55PM +0900, Benjamin Poirier wrote: On 2020-10-10 18:00 +0800, Coiby Xu wrote: [...] > > Please also update drivers/staging/qlge/TODO accordingly. There is still > a lot of debugging code IMO (the netif_printk statements - kernel > tracing can be used instead of those) but this patch is a substantial > improvement. Thank you for the reminding! To move qlge out of staging tree would be interesting exercise for me:) If you would like to work more on the driver, I would highly suggest getting one or two adapters to be able to test your changes. They can be had for relatively cheap on ebay. Just search for "qle8142". Thank you for the info! Right now I don't have a desktop to install this kind of adapter. I'll get one after settling the plan for a desktop. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Sat, Oct 10, 2020 at 10:48:55PM +0900, Benjamin Poirier wrote: On 2020-10-10 18:24 +0800, Coiby Xu wrote: On Sat, Oct 10, 2020 at 04:35:14PM +0900, Benjamin Poirier wrote: > On 2020-10-08 19:58 +0800, Coiby Xu wrote: > > Initialize devlink health dump framework for the dlge driver so the > > coredump could be done via devlink. > > > > Signed-off-by: Coiby Xu > > --- > > drivers/staging/qlge/Kconfig| 1 + > > drivers/staging/qlge/Makefile | 2 +- > > drivers/staging/qlge/qlge.h | 9 +++ > > drivers/staging/qlge/qlge_devlink.c | 38 + > > drivers/staging/qlge/qlge_devlink.h | 8 ++ > > drivers/staging/qlge/qlge_main.c| 28 + > > 6 files changed, 85 insertions(+), 1 deletion(-) > > create mode 100644 drivers/staging/qlge/qlge_devlink.c > > create mode 100644 drivers/staging/qlge/qlge_devlink.h > > > > diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig > > index a3cb25a3ab80..6d831ed67965 100644 > > --- a/drivers/staging/qlge/Kconfig > > +++ b/drivers/staging/qlge/Kconfig > > @@ -3,6 +3,7 @@ > > config QLGE > > tristate "QLogic QLGE 10Gb Ethernet Driver Support" > > depends on ETHERNET && PCI > > + select NET_DEVLINK > > help > > This driver supports QLogic ISP8XXX 10Gb Ethernet cards. > > > > diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile > > index 1dc2568e820c..07c1898a512e 100644 > > --- a/drivers/staging/qlge/Makefile > > +++ b/drivers/staging/qlge/Makefile > > @@ -5,4 +5,4 @@ > > > > obj-$(CONFIG_QLGE) += qlge.o > > > > -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o > > +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o > > diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h > > index b295990e361b..290e754450c5 100644 > > --- a/drivers/staging/qlge/qlge.h > > +++ b/drivers/staging/qlge/qlge.h > > @@ -2060,6 +2060,14 @@ struct nic_operations { > > int (*port_initialize)(struct ql_adapter *qdev); > > }; > > > > + > > + > > +struct qlge_devlink { > > +struct ql_adapter *qdev; > > +struct net_device *ndev; > > This member should be removed, it is unused throughout the rest of the > series. Indeed, it's simple to use qdev->ndev and that's what > qlge_reporter_coredump() does. It reminds me that I forgot to reply to one of your comments in RFC and sorry for that, > > + > > + > > +struct qlge_devlink { > > +struct ql_adapter *qdev; > > +struct net_device *ndev; > > I don't have experience implementing devlink callbacks but looking at > some other devlink users (mlx4, ionic, ice), all of them use devlink > priv space for their main private structure. That would be struct > ql_adapter in this case. Is there a good reason to stray from that > pattern? Thanks for getting back to that comment. struct ql_adapter which is created via alloc_etherdev_mq is the private space of struct net_device so we can't use ql_adapter as the the devlink private space simultaneously. Thus struct qlge_devlink is required. Looking at those drivers (mlx4, ionic, ice), the usage of alloc_etherdev_mq() is not really an obstacle. Definitely, some members would need to be moved from ql_adapter to qlge_devlink to use that pattern. I see what you mean now. I thought we were going to use struct ql_adapter as the shared private structure of devlink and net_device. If we are going to use ql_adapter as the private structure of devlink then we have to define another private structure for net_device. I think, but didn't check in depth, that in those drivers, the devlink device is tied to the pci device and can exist independently of the netdev, at least in principle. You are right. Take drivers/net/ethernet/mellanox/mlxsw as an example, devlink reload would first first unregister_netdev and then register_netdev but struct devlink stays put. But I have yet to understand when unregister/register_netdev is needed. Do we need to add "devlink reload" for qlge? In any case, I see now that some other drivers (bnxt, liquidio) have a pattern similar to what you use so I guess that's acceptable too. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Thu, Oct 08, 2020 at 08:22:44AM -0400, Willem de Bruijn wrote: On Thu, Oct 8, 2020 at 7:58 AM Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu @@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev, struct ql_adapter *qdev = NULL; static int cards_found; int err = 0; + struct devlink *devlink; + struct qlge_devlink *ql_devlink; + + devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink)); + if (!devlink) + return -ENOMEM; + ql_devlink = devlink_priv(devlink); ndev = alloc_etherdev_mq(sizeof(struct ql_adapter), min(MAX_CPUS, need to goto devlink_free instead of return -ENOMEM here, too. devlink_alloc return NULL only if kzalloc return NULL. So we shouldn't go to devlink_free which will call kfree. @@ -4614,6 +4624,16 @@ static int qlge_probe(struct pci_dev *pdev, free_netdev(ndev); return err; and here But I should goto devlink_free here. Thank you for pointing out my neglect. } + + err = devlink_register(devlink, >dev); + if (err) { + goto devlink_free; + } + + qlge_health_create_reporters(ql_devlink); + ql_devlink->qdev = qdev; + ql_devlink->ndev = ndev; + qdev->ql_devlink = ql_devlink; /* Start up the timer to trigger EEH if * the bus goes dead */ @@ -4624,6 +4644,10 @@ static int qlge_probe(struct pci_dev *pdev, atomic_set(>lb_count, 0); cards_found++; return 0; + +devlink_free: + devlink_free(devlink); + return err; } -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Sat, Oct 10, 2020 at 04:35:14PM +0900, Benjamin Poirier wrote: On 2020-10-08 19:58 +0800, Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 9 +++ drivers/staging/qlge/qlge_devlink.c | 38 + drivers/staging/qlge/qlge_devlink.h | 8 ++ drivers/staging/qlge/qlge_main.c| 28 + 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index b295990e361b..290e754450c5 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,14 @@ struct nic_operations { int (*port_initialize)(struct ql_adapter *qdev); }; + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; This member should be removed, it is unused throughout the rest of the series. Indeed, it's simple to use qdev->ndev and that's what qlge_reporter_coredump() does. It reminds me that I forgot to reply to one of your comments in RFC and sorry for that, + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; I don't have experience implementing devlink callbacks but looking at some other devlink users (mlx4, ionic, ice), all of them use devlink priv space for their main private structure. That would be struct ql_adapter in this case. Is there a good reason to stray from that pattern? struct ql_adapter which is created via alloc_etherdev_mq is the private space of struct net_device so we can't use ql_adapter as the the devlink private space simultaneously. Thus struct qlge_devlink is required. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter
On Sat, Oct 10, 2020 at 04:48:09PM +0900, Benjamin Poirier wrote: On 2020-10-08 19:58 +0800, Coiby Xu wrote: $ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 131 ++-- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index aa45e7e368c0..91b6600b94a9 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -1,16 +1,135 @@ #include "qlge.h" #include "qlge_devlink.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int fill_seg_(struct devlink_fmsg *fmsg, Please include the "qlge_" prefix. + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int i; + int header_size = sizeof(struct mpi_coredump_segment_header); + int regs_num = (seg_header->seg_size - header_size) / sizeof(u32); + int err; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define fill_seg(seg_hdr, seg_regs) \ considering that this macro accesses local variables, it is not really "function-like". I think an all-caps name would be better to tip-off the reader. Thank you for this suggestion! + do { \ + err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err;\ + } \ + } while (0) + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_devlink *dev = devlink_health_reporter_priv(reporter); Please name this variable ql_devlink, like in qlge_probe(). I happened to find the following text in drivers/staging/qlge/TODO * in terms of namespace, the driver uses either qlge_, ql_ (used by other qlogic drivers, with clashes, ex: ql_sem_spinlock) or nothing (with clashes, ex: struct ob_mac_iocb_req). Rename everything to use the "qlge_" prefix. So I will adopt qlge_ instead. Besides I prefer qlge_dl to ql_devlink. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
On Sat, Oct 10, 2020 at 05:01:26PM +0900, Benjamin Poirier wrote: On 2020-10-08 19:58 +0800, Coiby Xu wrote: The debugging code in the following ifdef land - QL_ALL_DUMP - QL_REG_DUMP - QL_DEV_DUMP - QL_CB_DUMP - QL_IB_DUMP - QL_OB_DUMP becomes unnecessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 688 drivers/staging/qlge/qlge_ethtool.c | 2 - drivers/staging/qlge/qlge_main.c| 7 +- Please also update drivers/staging/qlge/TODO accordingly. There is still a lot of debugging code IMO (the netif_printk statements - kernel tracing can be used instead of those) but this patch is a substantial improvement. Thank you for the reminding! To move qlge out of staging tree would be interesting exercise for me:) -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 2/6] staging: qlge: coredump via devlink health reporter
On Thu, Oct 08, 2020 at 04:39:40PM +0300, Dan Carpenter wrote: On Thu, Oct 08, 2020 at 07:58:04PM +0800, Coiby Xu wrote: -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int i; + int header_size = sizeof(struct mpi_coredump_segment_header); Please use the sizeof() directly in the code. Don't introduce indirection if you can help it. + int regs_num = (seg_header->seg_size - header_size) / sizeof(u32); + int err; + Thank you for the suggestion! regards, dan carpenter -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Thu, Oct 08, 2020 at 04:31:42PM +0300, Dan Carpenter wrote: On Thu, Oct 08, 2020 at 07:58:03PM +0800, Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 9 +++ drivers/staging/qlge/qlge_devlink.c | 38 + drivers/staging/qlge/qlge_devlink.h | 8 ++ drivers/staging/qlge/qlge_main.c| 28 + 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index b295990e361b..290e754450c5 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,14 @@ struct nic_operations { int (*port_initialize)(struct ql_adapter *qdev); }; + + Having multiple blank lines in a row leads to a static checker warning. Please run `checkpatch.pl --strict` over your patches. +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; +struct devlink_health_reporter *reporter; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2077,6 +2085,7 @@ struct ql_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct qlge_devlink *ql_devlink; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c new file mode 100644 index ..aa45e7e368c0 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.c @@ -0,0 +1,38 @@ +#include "qlge.h" +#include "qlge_devlink.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, Indented too far. +}; + +int qlge_health_create_reporters(struct qlge_devlink *priv) +{ + int err; + No blanks in the middle of declarations. + struct devlink_health_reporter *reporter; + struct devlink *devlink; Generally this driver declares variables in "Reverse Christmas Tree" order. The names are orderred by the length of the line from longest to shortest. type long_name; type medium; type short; + + devlink = priv_to_devlink(priv); + reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, + priv); Break this up like so: reporter = devlink_health_reporter_create(devlink, _reporter_ops, 0, priv); + if (IS_ERR(reporter)) { + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); + return PTR_ERR(reporter); No point in returning an error if the caller doesn't check? + } + priv->reporter = reporter; + + return err; err is uninitialized. "return 0;" +} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h new file mode 100644 index ..c91f7a29e805 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.h @@ -0,0 +1,8 @@ +#ifndef QLGE_DEVLINK_H +#define QLGE_DEVLINK_H + +#include + +int qlge_health_create_reporters(struct qlge_devlink *priv); + +#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 27da386f9d87..135225530e51 100644 --- a/drivers/staging/qlge/qlge_main.c ++
Re: [PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
On Thu, Oct 08, 2020 at 08:22:44AM -0400, Willem de Bruijn wrote: On Thu, Oct 8, 2020 at 7:58 AM Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu @@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev, struct ql_adapter *qdev = NULL; static int cards_found; int err = 0; + struct devlink *devlink; + struct qlge_devlink *ql_devlink; + + devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink)); + if (!devlink) + return -ENOMEM; + ql_devlink = devlink_priv(devlink); ndev = alloc_etherdev_mq(sizeof(struct ql_adapter), min(MAX_CPUS, need to goto devlink_free instead of return -ENOMEM here, too. @@ -4614,6 +4624,16 @@ static int qlge_probe(struct pci_dev *pdev, free_netdev(ndev); return err; and here Thank you for reviewing this work and the speedy feedback! I'll fix it in v2. } + + err = devlink_register(devlink, >dev); + if (err) { + goto devlink_free; + } + + qlge_health_create_reporters(ql_devlink); + ql_devlink->qdev = qdev; + ql_devlink->ndev = ndev; + qdev->ql_devlink = ql_devlink; /* Start up the timer to trigger EEH if * the bus goes dead */ @@ -4624,6 +4644,10 @@ static int qlge_probe(struct pci_dev *pdev, atomic_set(>lb_count, 0); cards_found++; return 0; + +devlink_free: + devlink_free(devlink); + return err; } -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v1 5/6] staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land
The debugging code in the following ifdef land - QL_ALL_DUMP - QL_REG_DUMP - QL_DEV_DUMP - QL_CB_DUMP - QL_IB_DUMP - QL_OB_DUMP becomes unnecessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 688 drivers/staging/qlge/qlge_ethtool.c | 2 - drivers/staging/qlge/qlge_main.c| 7 +- 4 files changed, 1 insertion(+), 778 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 0a39801be15a..8aff3ba77730 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2285,86 +2285,4 @@ void ql_check_lb_frame(struct ql_adapter *qdev, struct sk_buff *skb); int ql_own_firmware(struct ql_adapter *qdev); int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); -/* #define QL_ALL_DUMP */ -/* #define QL_REG_DUMP */ -/* #define QL_DEV_DUMP */ -/* #define QL_CB_DUMP */ -/* #define QL_IB_DUMP */ -/* #define QL_OB_DUMP */ - -#ifdef QL_REG_DUMP -void ql_dump_xgmac_control_regs(struct ql_adapter *qdev); -void ql_dump_routing_entries(struct ql_adapter *qdev); -void ql_dump_regs(struct ql_adapter *qdev); -#define QL_DUMP_REGS(qdev) ql_dump_regs(qdev) -#define QL_DUMP_ROUTE(qdev) ql_dump_routing_entries(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) ql_dump_xgmac_control_regs(qdev) -#else -#define QL_DUMP_REGS(qdev) -#define QL_DUMP_ROUTE(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) -#endif - -#ifdef QL_STAT_DUMP -void ql_dump_stat(struct ql_adapter *qdev); -#define QL_DUMP_STAT(qdev) ql_dump_stat(qdev) -#else -#define QL_DUMP_STAT(qdev) -#endif - -#ifdef QL_DEV_DUMP -void ql_dump_qdev(struct ql_adapter *qdev); -#define QL_DUMP_QDEV(qdev) ql_dump_qdev(qdev) -#else -#define QL_DUMP_QDEV(qdev) -#endif - -#ifdef QL_CB_DUMP -void ql_dump_wqicb(struct wqicb *wqicb); -void ql_dump_tx_ring(struct tx_ring *tx_ring); -void ql_dump_ricb(struct ricb *ricb); -void ql_dump_cqicb(struct cqicb *cqicb); -void ql_dump_rx_ring(struct rx_ring *rx_ring); -void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ - ql_dump_hw_cb(qdev, size, bit, q_id) -#else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) -#endif - -#ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) -#else -#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) -#endif - -#ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) -#else -#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) -#endif - -#ifdef QL_ALL_DUMP -void ql_dump_all(struct ql_adapter *qdev); -#define QL_DUMP_ALL(qdev) ql_dump_all(qdev) -#else -#define QL_DUMP_ALL(qdev) -#endif - #endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 989575743718..a02ecf8fb291 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1313,691 +1313,3 @@ void ql_get_dump(struct ql_adapter *qdev, void *buff) ql_get_core_dump(qdev); } } - -#ifdef QL_REG_DUMP -static void ql_dump_intr_states(struct ql_adapter *qdev) -{ - int i; - u32 value; - - for (i = 0; i < qdev->intr_count; i++) { - ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask); - value = ql_read32(qdev, INTR_EN); - netdev_err(qdev->ndev, "Interrupt %d is %s\n", i, - (value & INTR_EN_EN ? "enabled" : "disabled")); - } -} - -#define DUMP_XGMAC(qdev, reg) \ -do { \ - u32 data; \ - ql_read_xgmac_reg(qdev, reg, );
[PATCH v1 2/6] staging: qlge: coredump via devlink health reporter
$ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 131 ++-- 1 file changed, 125 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index aa45e7e368c0..91b6600b94a9 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -1,16 +1,135 @@ #include "qlge.h" #include "qlge_devlink.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int i; + int header_size = sizeof(struct mpi_coredump_segment_header); + int regs_num = (seg_header->seg_size - header_size) / sizeof(u32); + int err; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define fill_seg(seg_hdr, seg_regs) \ + do { \ + err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err;\ + } \ + } while (0) + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_devlink *dev = devlink_health_reporter_priv(reporter); + struct ql_adapter *qdev = dev->qdev; + struct ql_mpi_coredump *dump; + + if (!netif_running(qdev->ndev)) + return 0; + + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); + if (!dump) + return -ENOMEM; + + err = ql_core_dump(qdev, dump); + if (err) { + kvfree(dump); + return err; + } + + fill_seg(core_regs_seg_hdr, mpi_core_regs); + fill_seg(test_logic_regs_seg_hdr, test_logic_regs); + fill_seg(rmii_regs_seg_hdr, rmii_regs); + fill_seg(fcmac1_regs_seg_hdr, fcmac1_regs); + fill_seg(fcmac2_regs_seg_hdr, fcmac2_regs); + fill_seg(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); + fill_seg(ide_regs_seg_hdr, ide_regs); + fill_seg(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); + fill_seg(smbus_regs_seg_hdr, smbus_regs); + fill_seg(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); + fill_seg(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); + fill_seg(i2c_regs_seg_hdr, i2c_regs); + fill_seg(memc_regs_seg_hdr, memc_regs); + fill_seg(pbus_regs_seg_hdr, pbus_regs); + fill_seg(mde_regs_seg_hdr, md
[PATCH v1 6/6] staging: qlge: add documentation for debugging qlge
Instructions and examples on kernel data structures dumping and coredump. Signed-off-by: Coiby Xu --- .../networking/device_drivers/index.rst | 1 + .../device_drivers/qlogic/index.rst | 18 +++ .../networking/device_drivers/qlogic/qlge.rst | 118 ++ MAINTAINERS | 6 + 4 files changed, 143 insertions(+) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst index a3113ffd7a16..d8279de7bf25 100644 --- a/Documentation/networking/device_drivers/index.rst +++ b/Documentation/networking/device_drivers/index.rst @@ -15,6 +15,7 @@ Contents: ethernet/index fddi/index hamradio/index + qlogic/index wan/index wifi/index diff --git a/Documentation/networking/device_drivers/qlogic/index.rst b/Documentation/networking/device_drivers/qlogic/index.rst new file mode 100644 index ..ad05b04286e4 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/index.rst @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +QLogic QLGE Device Drivers +=== + +Contents: + +.. toctree:: + :maxdepth: 2 + + qlge + +.. only:: subproject and html + + Indices + === + + * :ref:`genindex` diff --git a/Documentation/networking/device_drivers/qlogic/qlge.rst b/Documentation/networking/device_drivers/qlogic/qlge.rst new file mode 100644 index ..0b888253d152 --- /dev/null +++ b/Documentation/networking/device_drivers/qlogic/qlge.rst @@ -0,0 +1,118 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=== +QLogic QLGE 10Gb Ethernet device driver +=== + +This driver use drgn and devlink for debugging. + +Dump kernel data structures in drgn +--- + +To dump kernel data structures, the following Python script can be used +in drgn: + +.. code-block:: python + + def align(x, a): + """the alignment a should be a power of 2 + """ + mask = a - 1 + return (x+ mask) & ~mask + + def struct_size(struct_type): + struct_str = "struct {}".format(struct_type) + return sizeof(Object(prog, struct_str, address=0x0)) + + def netdev_priv(netdevice): + NETDEV_ALIGN = 32 + return netdevice.value_() + align(struct_size("net_device"), NETDEV_ALIGN) + + name = 'xxx' + qlge_device = None + netdevices = prog['init_net'].dev_base_head.address_of_() + for netdevice in list_for_each_entry("struct net_device", netdevices, "dev_list"): + if netdevice.name.string_().decode('ascii') == name: + print(netdevice.name) + + ql_adapter = Object(prog, "struct ql_adapter", address=netdev_priv(qlge_device)) + +The struct ql_adapter will be printed in drgn as follows, + +>>> ql_adapter +(struct ql_adapter){ +.ricb = (struct ricb){ +.base_cq = (u8)0, +.flags = (u8)120, +.mask = (__le16)26637, +.hash_cq_id = (u8 [1024]){ 172, 142, 255, 255 }, +.ipv6_hash_key = (__le32 [10]){}, +.ipv4_hash_key = (__le32 [4]){}, +}, +.flags = (unsigned long)0, +.wol = (u32)0, +.nic_stats = (struct nic_stats){ +.tx_pkts = (u64)0, +.tx_bytes = (u64)0, +.tx_mcast_pkts = (u64)0, +.tx_bcast_pkts = (u64)0, +.tx_ucast_pkts = (u64)0, +.tx_ctl_pkts = (u64)0, +.tx_pause_pkts = (u64)0, +... +}, +.active_vlans = (unsigned long [64]){ +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52780853100545, 18446744073709551615, +18446619461681283072, 0, 42949673024, 2147483647, +}, +.rx_ring = (struct rx_ring [17]){ +{ +.cqicb = (struct cqicb){ +.msix_vect = (u8)0, +.reserved1 = (u8)0, +.reserved2 = (u8)0, +.flags = (u8)0, +.len = (__le16)0, +.rid = (__le16)0, +... +}, +
[PATCH v1 1/6] staging: qlge: Initialize devlink health dump framework for the dlge driver
Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Kconfig| 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 9 +++ drivers/staging/qlge/qlge_devlink.c | 38 + drivers/staging/qlge/qlge_devlink.h | 8 ++ drivers/staging/qlge/qlge_main.c| 28 + 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h diff --git a/drivers/staging/qlge/Kconfig b/drivers/staging/qlge/Kconfig index a3cb25a3ab80..6d831ed67965 100644 --- a/drivers/staging/qlge/Kconfig +++ b/drivers/staging/qlge/Kconfig @@ -3,6 +3,7 @@ config QLGE tristate "QLogic QLGE 10Gb Ethernet Driver Support" depends on ETHERNET && PCI + select NET_DEVLINK help This driver supports QLogic ISP8XXX 10Gb Ethernet cards. diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..07c1898a512e 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_devlink.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index b295990e361b..290e754450c5 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2060,6 +2060,14 @@ struct nic_operations { int (*port_initialize)(struct ql_adapter *qdev); }; + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; +struct devlink_health_reporter *reporter; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2077,6 +2085,7 @@ struct ql_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct qlge_devlink *ql_devlink; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c new file mode 100644 index ..aa45e7e368c0 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.c @@ -0,0 +1,38 @@ +#include "qlge.h" +#include "qlge_devlink.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; + +int qlge_health_create_reporters(struct qlge_devlink *priv) +{ + int err; + + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, + priv); + if (IS_ERR(reporter)) { + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); + return PTR_ERR(reporter); + } + priv->reporter = reporter; + + return err; +} diff --git a/drivers/staging/qlge/qlge_devlink.h b/drivers/staging/qlge/qlge_devlink.h new file mode 100644 index ..c91f7a29e805 --- /dev/null +++ b/drivers/staging/qlge/qlge_devlink.h @@ -0,0 +1,8 @@ +#ifndef QLGE_DEVLINK_H +#define QLGE_DEVLINK_H + +#include + +int qlge_health_create_reporters(struct qlge_devlink *priv); + +#endif /* QLGE_DEVLINK_H */ diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 27da386f9d87..135225530e51 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -42,6 +42,7 @@ #include #include "qlge.h" +#include "qlge_devlink.h" char qlge_driver_name[] = DRV_NAME; const char qlge_driver_version[] = DRV_VERSION; @@ -4549,6 +4550,8 @@ static void ql_timer(struct timer_list *t) mod_timer(>timer, jiffies + (5 * HZ)); } +static const struct devlink_ops qlge_devlink_ops; + static int qlge_probe(struct pci_dev *pdev, const struct pci_device_id *pci_entry) { @@ -4556,6 +4559,13 @@ static int qlge_probe(struct pci_dev *pdev, struct ql_adapter *qdev = NULL; static int cards_found; int err = 0; + struct devlink *devlink; + struct qlge_devlink *ql_devlink; + + devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink)); +
[PATCH v1 0/6] staging: qlge: Re-writing the debugging features
This patch set aims to avoid dumping registers, data structures and coredump to dmesg and also to reduce the code size of the qlge driver. As pointed out by Benjamin [1], > At 2000 lines, qlge_dbg.c alone is larger than some entire ethernet > drivers. Most of what it does is dump kernel data structures or pci > memory mapped registers to dmesg. There are better facilities for that. > My thinking is not simply to delete qlge_dbg.c but to replace it, making > sure that most of the same information is still available. For data > structures, crash or drgn can be used; possibly with a script for the > latter which formats the data. For pci registers, they should be > included in the ethtool register dump and a patch added to ethtool to > pretty print them. That's what other drivers like e1000e do. For the > "coredump", devlink health can be used. So the debugging features are re-written following Benjamin's advice, - dump kernel data structures in drgn - use devlink to do coredump which also includes device status and general registers [1] https://lkml.org/lkml/2020/6/30/19 Change since RFC: - select NET_DEVLINK in Kconfig [Benjamin Poirier] - Don't do a coredump when the interface is down [Shung-Hsi Yu] - Remove stray newlines [Benjamin Poirier] - force_coredump for devlink - Remove mpi_core_to_log which will output the coredump to the kernel ring buffer - Put drgn script under Documentation [Benjamin Poirier] - Rename qlge_health.* to qlge_devlink.* Coiby Xu (6): staging: qlge: Initialize devlink health dump framework for the dlge driver staging: qlge: coredump via devlink health reporter staging: qlge: support force_coredump option for devlink health dump staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer staging: qlge: clean up debugging code in the QL_ALL_DUMP ifdef land staging: qlge: add documentation for debugging qlge .../networking/device_drivers/index.rst | 1 + .../device_drivers/qlogic/index.rst | 18 + .../networking/device_drivers/qlogic/qlge.rst | 118 +++ MAINTAINERS | 6 + drivers/staging/qlge/Kconfig | 1 + drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h | 94 +-- drivers/staging/qlge/qlge_dbg.c | 699 -- drivers/staging/qlge/qlge_devlink.c | 164 drivers/staging/qlge/qlge_devlink.h | 8 + drivers/staging/qlge/qlge_ethtool.c | 3 - drivers/staging/qlge/qlge_main.c | 37 +- drivers/staging/qlge/qlge_mpi.c | 6 - 13 files changed, 355 insertions(+), 802 deletions(-) create mode 100644 Documentation/networking/device_drivers/qlogic/index.rst create mode 100644 Documentation/networking/device_drivers/qlogic/qlge.rst create mode 100644 drivers/staging/qlge/qlge_devlink.c create mode 100644 drivers/staging/qlge/qlge_devlink.h -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v1 3/6] staging: qlge: support force_coredump option for devlink health dump
With force_coredump module paramter set, devlink health dump will reset the MPI RISC first which takes 5 secs to be finished. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_devlink.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/qlge/qlge_devlink.c b/drivers/staging/qlge/qlge_devlink.c index 91b6600b94a9..54257468bc7f 100644 --- a/drivers/staging/qlge/qlge_devlink.c +++ b/drivers/staging/qlge/qlge_devlink.c @@ -56,10 +56,17 @@ static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, struct qlge_devlink *dev = devlink_health_reporter_priv(reporter); struct ql_adapter *qdev = dev->qdev; struct ql_mpi_coredump *dump; + wait_queue_head_t wait; if (!netif_running(qdev->ndev)) return 0; + if (test_bit(QL_FRC_COREDUMP, >flags)) { + ql_queue_fw_error(qdev); + init_waitqueue_head(); + wait_event_timeout(wait, 0, 5 * HZ); + } + dump = kvmalloc(sizeof(*dump), GFP_KERNEL); if (!dump) return -ENOMEM; -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v1 4/6] staging: qlge: remove mpi_core_to_log which sends coredump to the kernel ring buffer
devlink health could be used to get coredump. No need to send so much data to the kernel ring buffer. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 3 --- drivers/staging/qlge/qlge_dbg.c | 11 --- drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 2 -- drivers/staging/qlge/qlge_mpi.c | 6 -- 5 files changed, 23 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 290e754450c5..0a39801be15a 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2149,7 +2149,6 @@ struct ql_adapter { u32 port_init; u32 link_status; struct ql_mpi_coredump *mpi_coredump; - u32 core_is_dumped; u32 link_config; u32 led_config; u32 max_frame_size; @@ -2162,7 +2161,6 @@ struct ql_adapter { struct delayed_work mpi_work; struct delayed_work mpi_port_cfg_work; struct delayed_work mpi_idc_work; - struct delayed_work mpi_core_to_log; struct completion ide_completion; const struct nic_operations *nic_ops; u16 device_id; @@ -2253,7 +2251,6 @@ int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit, void ql_queue_fw_error(struct ql_adapter *qdev); void ql_mpi_work(struct work_struct *work); void ql_mpi_reset_work(struct work_struct *work); -void ql_mpi_core_to_log(struct work_struct *work); int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit); void ql_queue_asic_error(struct ql_adapter *qdev); void ql_set_ethtool_ops(struct net_device *ndev); diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 42fd13990f3a..989575743718 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1314,17 +1314,6 @@ void ql_get_dump(struct ql_adapter *qdev, void *buff) } } -/* Coredump to messages log file using separate worker thread */ -void ql_mpi_core_to_log(struct work_struct *work) -{ - struct ql_adapter *qdev = - container_of(work, struct ql_adapter, mpi_core_to_log.work); - - print_hex_dump(KERN_DEBUG, "Core is dumping to log file!\n", - DUMP_PREFIX_OFFSET, 32, 4, qdev->mpi_coredump, - sizeof(*qdev->mpi_coredump), false); -} - #ifdef QL_REG_DUMP static void ql_dump_intr_states(struct ql_adapter *qdev) { diff --git a/drivers/staging/qlge/qlge_ethtool.c b/drivers/staging/qlge/qlge_ethtool.c index d44b2dae9213..eed116d8895e 100644 --- a/drivers/staging/qlge/qlge_ethtool.c +++ b/drivers/staging/qlge/qlge_ethtool.c @@ -616,7 +616,6 @@ static void ql_get_regs(struct net_device *ndev, struct ql_adapter *qdev = netdev_priv(ndev); ql_get_dump(qdev, p); - qdev->core_is_dumped = 0; if (!test_bit(QL_FRC_COREDUMP, >flags)) regs->len = sizeof(struct ql_mpi_coredump); else diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 135225530e51..aaca740d46c4 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3808,7 +3808,6 @@ static void ql_cancel_all_work_sync(struct ql_adapter *qdev) cancel_delayed_work_sync(>mpi_reset_work); cancel_delayed_work_sync(>mpi_work); cancel_delayed_work_sync(>mpi_idc_work); - cancel_delayed_work_sync(>mpi_core_to_log); cancel_delayed_work_sync(>mpi_port_cfg_work); } @@ -4504,7 +4503,6 @@ static int ql_init_device(struct pci_dev *pdev, struct net_device *ndev, INIT_DELAYED_WORK(>mpi_work, ql_mpi_work); INIT_DELAYED_WORK(>mpi_port_cfg_work, ql_mpi_port_cfg_work); INIT_DELAYED_WORK(>mpi_idc_work, ql_mpi_idc_work); - INIT_DELAYED_WORK(>mpi_core_to_log, ql_mpi_core_to_log); init_completion(>ide_completion); mutex_init(>mpi_mutex); diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 143a886080c5..1cea24201b17 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -1269,11 +1269,5 @@ void ql_mpi_reset_work(struct work_struct *work) return; } - if (qdev->mpi_coredump && !ql_core_dump(qdev, qdev->mpi_coredump)) { - netif_err(qdev, drv, qdev->ndev, "Core is dumped!\n"); - qdev->core_is_dumped = 1; - queue_delayed_work(qdev->workqueue, - >mpi_core_to_log, 5 * HZ); - } ql_soft_reset_mpi_risc(qdev); } -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/3] staging: greybus: fix warnings about endianness detected by sparse
On Tue, Oct 06, 2020 at 12:47:37AM +0530, Vaibhav Agarwal wrote: On Sat, Oct 3, 2020 at 5:01 AM Coiby Xu wrote: This patch fix the following warnings from sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 [usertype] access drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32 drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32 drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32 drivers/staging/greybus/audio_topology.c:805:50:got unsigned int drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32 drivers/staging/greybus/audio_topology.c:817:58:got unsigned int drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 [usertype] access Suggested-by: Dan Carpenter Reviewed-by: Dan Carpenter Reviewed-by: Alex Elder Signed-off-by: Coiby Xu --- Hi Coiby, Thanks for sharing the patch. Sorry, I could not reply to the v1 series. Now, I have gone through the patches. Looks good (all 3 patches). Reviewed-by: Vaibhav Agarwal -- Thanks, Hi Vaibhav, Thank you for reviewing these patches and giving the credit! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [RFC 1/3] Initialize devlink health dump framework for the dlge driver
On Fri, Aug 21, 2020 at 11:08:22AM +0800, Coiby Xu wrote: On Sun, Aug 16, 2020 at 11:56:40AM +0900, Benjamin Poirier wrote: On 2020-08-15 00:05 +0800, Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h| 9 +++ drivers/staging/qlge/qlge_health.c | 43 ++ drivers/staging/qlge/qlge_health.h | 2 ++ drivers/staging/qlge/qlge_main.c | 21 +++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_health.c create mode 100644 drivers/staging/qlge/qlge_health.h diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..0a1e4c8dd546 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index fc8c5ca8935d..055ded6dab60 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2061,6 +2061,14 @@ struct nic_operations { int (*port_initialize) (struct ql_adapter *); }; This patch doesn't apply over the latest staging tree. I think your tree is missing commit d923bb6bf508 ("staging: qlge: qlge.h: Function definition arguments should have names.") Thank you for applying the patch to test it! I had incorrect understanding about the word "RFC" and didn't do a rebase onto the latest staging tree. + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; I don't have experience implementing devlink callbacks but looking at some other devlink users (mlx4, ionic, ice), all of them use devlink priv space for their main private structure. That would be struct ql_adapter in this case. Is there a good reason to stray from that pattern? +struct devlink_health_reporter *reporter; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2078,6 +2086,7 @@ struct ql_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct qlge_devlink *devlink; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_health.c b/drivers/staging/qlge/qlge_health.c new file mode 100644 index ..292f6b1827e1 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.c @@ -0,0 +1,43 @@ +#include "qlge.h" +#include "qlge_health.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; I think select NET_DEVLINK should be added to drivers/staging/qlge/Kconfig Thank you for reminding me! + +int qlge_health_create_reporters(struct qlge_devlink *priv) +{ + int err; + + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, + priv); + if (IS_ERR(reporter)) { + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); + return PTR_ERR(reporter); + } + priv->reporter = reporter; + + if (err) + return err; + + return 0; +} + + Stray newlines Will fix it in v1. diff --git a/drivers/staging/qlge/qlge_health.h b/drivers/staging/qlge/qlge_health.h new file mode 100644 index ..07d3bafab845 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.h @@ -0,0 +1,2 @@ +#include +int qlge_health_create_reporters(struct qlge_devlink *priv); I would suggest to put this in qlge.h instead of creating a new file. Although there are only two lines for now, is it possible qlge will add more devlink code? If that's the case, a file to single out these code is necessary as is the same to some other drivers, $ find drivers -name *health*.h drivers/net/ethernet/mellanox/mlx5/core/en/health.h $ find drivers -name *devlink*.h drivers/net/ethernet/huawei/hinic/hinic_devlink.h drivers/net/ethernet/mellanox/mlx5/core/devlink.h drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h dr
Re: [PATCH v4] staging: qlge: fix build breakage with dumping enabled
On Sat, Oct 03, 2020 at 02:53:48PM +0900, Benjamin Poirier wrote: On 2020-10-03 07:59 +0800, Coiby Xu wrote: This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="-DQL_ALL_DUMP -DQL_OB_DUMP -DQL_CB_DUMP \ -DQL_IB_DUMP -DQL_REG_DUMP -DQL_DEV_DUMP" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Note that now ql_dump_rx_ring/ql_dump_tx_ring won't check if the passed parameter is a null pointer. Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- Reviewed-by: Benjamin Poirier Thank you! Btw, I guess when this patch is picked, the "Reviewed-by" tag will also be included. So I needn't to send another patch, am I right? -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4] staging: qlge: fix build breakage with dumping enabled
This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="-DQL_ALL_DUMP -DQL_OB_DUMP -DQL_CB_DUMP \ -DQL_IB_DUMP -DQL_REG_DUMP -DQL_DEV_DUMP" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Note that now ql_dump_rx_ring/ql_dump_tx_ring won't check if the passed parameter is a null pointer. Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 20 ++-- drivers/staging/qlge/qlge_dbg.c | 28 ++-- drivers/staging/qlge/qlge_main.c | 8 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 48f346503979..b295990e361b 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2337,21 +2337,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #endif #ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) #else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) #endif #ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) #else -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) #endif #ifdef QL_ALL_DUMP diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index a55bf0b3e9dc..42fd13990f3a 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) } if (value) netdev_err(qdev->ndev, - "%s: Routing Mask %d = 0x%.08x\n", + "Routing Mask %d = 0x%.08x\n", i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); @@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev) #ifdef QL_CB_DUMP void ql_dump_wqicb(struct wqicb *wqicb) { + struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); netdev_err(qdev->ndev, "wqicb->flags = %x\n", @@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { - if (!tx_ring) - return; + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "= Dumping tx_ring %d ===\n", tx_ring->wq_id);
[PATCH v2 1/3] staging: greybus: fix warnings about endianness detected by sparse
This patch fix the following warnings from sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 [usertype] access drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32 drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32 drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32 drivers/staging/greybus/audio_topology.c:805:50:got unsigned int drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32 drivers/staging/greybus/audio_topology.c:817:58:got unsigned int drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 [usertype] access Suggested-by: Dan Carpenter Reviewed-by: Dan Carpenter Reviewed-by: Alex Elder Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_module.c | 6 +++--- drivers/staging/greybus/audio_topology.c | 18 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 16f60256adb2..c52c4f361b90 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, greybus_set_drvdata(bundle, gbmodule); dai->id = 0; - dai->data_cport = connection->intf_cport_id; + dai->data_cport = cpu_to_le16(connection->intf_cport_id); dai->connection = connection; list_add(>list, >data_list); @@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle, if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); goto disable_data_connection; } } @@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev) if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); return ret; } } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 83b38ae8908c..2091031659de 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, goto exit; /* update ucontrol */ - if (gbvalue.value.integer_value[0] != val) { + if (le32_to_cpu(gbvalue.value.integer_value[0]) != val) { for (wi = 0; wi < wlist->num_widgets; wi++) { widget = wlist->widgets[wi]; snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, @@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_t
[PATCH v2 2/3] staging: greybus: codecs: use SNDRV_PCM_FMTBIT_S16_LE for format bitmask
snd_soc_pcm_stream.formats should use the bitmask SNDRV_PCM_FMTBIT_* instead of the sequential integers SNDRV_PCM_FORMAT_* as explained by commit e712bfca1ac1f63f622f87c2f33b57608f2a4d19 ("ASoC: codecs: use SNDRV_PCM_FMTBIT_* for format bitmask"). Found by sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:691:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:701:36:got restricted snd_pcm_format_t [usertype] Reviewed-by: Alex Elder Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 74538f8c5fa4..494aa823e998 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .playback = { .stream_name = "I2S 0 Playback", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .capture = { .stream_name = "I2S 0 Capture", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 3/3] staging: greybus: use __force when assigning __u8 value to snd_ctl_elem_type_t
(struct gb_audio_ctl_elem_info*)->type has the type of __u8 so there is no concern about the byte order. __force is safe to use. Found by sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted snd_ctl_elem_type_t Suggested-by: Alex Elder Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 2091031659de..662e3e8b4b63 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, /* update uinfo */ uinfo->access = data->access; uinfo->count = data->vcount; - uinfo->type = (snd_ctl_elem_type_t)info->type; + uinfo->type = (__force snd_ctl_elem_type_t)info->type; switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t
On Fri, Sep 25, 2020 at 10:57:27AM -0500, Alex Elder wrote: On 9/25/20 9:07 AM, Coiby Xu wrote: On Thu, Sep 24, 2020 at 01:00:57PM +0200, Greg Kroah-Hartman wrote: On Thu, Sep 24, 2020 at 06:20:39PM +0800, Coiby Xu wrote: Use __8 to replace int and remove the unnecessary __bitwise type attribute. Found by sparse, . . . diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 535a7229e1d9..8e71a95644ab 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -950,7 +950,7 @@ struct snd_ctl_card_info { unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ }; -typedef int __bitwise snd_ctl_elem_type_t; +typedef __u8 snd_ctl_elem_type_t; #define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */ #define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ #define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ @@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t; #define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ #define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64 -typedef int __bitwise snd_ctl_elem_iface_t; +typedef __u8 snd_ctl_elem_iface_t; #define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ #define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ #define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ I can't take a uapi sound header file patch along with a driver change, these need to be independant. Thank you and Alex for reminding me this is a change of public header! And this is a userspace api, you just changed the size of an externally facing variable, are you _SURE_ that is ok to do? The reasons I make this change are, 1) using int to represent 7 enumeration values seems to be overkill; 2) using one type could avoid worries about byte order. (1) might be a valid suggestion, but the file you suggest changing is part of the Linux user space API, which you basically can't change. I'm fairly certain the user space API is defined to have CPU-local byte order (unless specified explicitly otherwise) so that is not a concern. Thank you for sharing me about the byte order of user space API which prompts me to examine where "info->type" comes from, uinfo->type = (snd_ctl_elem_type_t)info->type; Eventually it comes from the parsed topology data which is obtained via gb_audio_gb_get_topology(gbmodule->mgmt_connection, ). But since (struct gb_audio_ctl_elem_info*)->type has __u8 type, there is no endianness concern. Then based on the principles of userspace API shouldn't be modified and greybus is operating system independent, your previous suggestion to use __force which means "I know what I'm doing" is actually a good idea, uinfo->type = (__force snd_ctl_elem_type_t)info->type; I examine one userspace example (libalsa-intf/alsa_mixer.c [1]). This change won't cause compiling breakage. But I don't the experience to imagine any other bad consequence. As a rule, once the user space API has been established, it stays with us forever. You can add to it, but modifying (or removing) an existing interface is essentially forbidden. Another way to avoid userspace API change is to let "struct gb_audio_ctl_elem_info" use snd_ctl_elem_iface_t type which may be more elegant than using "__force" as suggested by Alex, The Greybus definitions were explicitly defined to be operating system independent. For that reason there are (admittedly cumbersome) definitions of certain types and values that essentially mimic those defined by Linux exactly That way Linux (or another system using Greybus) can change its internal values without changing the Greybus API definition. (This addresses the concern you mention below.) What you are suggesting is not consistent with that principle. -Alex $ git diff diff --git a/include/linux/greybus/greybus_protocols.h b/include/linux/greybus/greybus_protocols.h index aeb8f9243545..7f6753ec7ef7 100644 --- a/include/linux/greybus/greybus_protocols.h +++ b/include/linux/greybus/greybus_protocols.h @@ -8,6 +8,7 @@ #define __GREYBUS_PROTOCOLS_H #include +#include /* Fixed IDs for control/svc protocols */ @@ -1997,7 +1998,7 @@ struct gb_audio_enumerated { } __packed; struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux source */ - __u8 type; /* GB_AUDIO_CTL_ELEM_TYPE_* */ + snd_ctl_elem_type_t type; /* GB_AUDIO_CTL_ELEM_TYPE_* */ __le16 dimen[4]; union { struct gb_audio_integer integer
Re: [greybus-dev] [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t
On Fri, Sep 25, 2020 at 11:02:23AM -0500, Alex Elder wrote: On 9/25/20 9:11 AM, Coiby Xu wrote: On Thu, Sep 24, 2020 at 10:54:50AM +, David Laight wrote: From: Coiby Xu Sent: 24 September 2020 11:21 Use __8 to replace int and remove the unnecessary __bitwise type attribute. Found by sparse, ... diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 535a7229e1d9..8e71a95644ab 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -950,7 +950,7 @@ struct snd_ctl_card_info { unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ }; -typedef int __bitwise snd_ctl_elem_type_t; +typedef __u8 snd_ctl_elem_type_t; #define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */ #define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ #define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ WTF is all that about anyway?? What is wrong with: #define SNDRV_CTL_ELEM_TYPE_NONE 0u /* invalid */ I'm sorry I don't quite understand you. Are you suggesting SNDRV_CTL_ELEM_TYPE_NONE isn't needed in the first place? I think David is asking why it's defined the way it is, and I'd guess it's to have the compiler issue an error if you attempt to assign one of these values to a variable or field of the wrong type. No, you should not attempt to change this. Thank you for the explanation! -Alex David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) -- Best regards, Coiby ___ greybus-dev mailing list greybus-...@lists.linaro.org https://lists.linaro.org/mailman/listinfo/greybus-dev -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t
On Thu, Sep 24, 2020 at 10:54:50AM +, David Laight wrote: From: Coiby Xu Sent: 24 September 2020 11:21 Use __8 to replace int and remove the unnecessary __bitwise type attribute. Found by sparse, ... diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 535a7229e1d9..8e71a95644ab 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -950,7 +950,7 @@ struct snd_ctl_card_info { unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ }; -typedef int __bitwise snd_ctl_elem_type_t; +typedef __u8 snd_ctl_elem_type_t; #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 0) /* invalid */ #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ WTF is all that about anyway?? What is wrong with: #define SNDRV_CTL_ELEM_TYPE_NONE0u /* invalid */ I'm sorry I don't quite understand you. Are you suggesting SNDRV_CTL_ELEM_TYPE_NONE isn't needed in the first place? David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [greybus-dev] [PATCH 1/3] [PATCH] staging: greybus: fix warnings about endianness detected by sparse
On Thu, Sep 24, 2020 at 07:50:57AM -0500, Alex Elder wrote: On 9/24/20 5:20 AM, Coiby Xu wrote: This patch fix the following warnings from sparse, You need to address Greg's comment. But in general this looks good. I have one comment below, which you can address in v2. If you (or others) disagree with it, I'm fine with your code as-is. Either way, you can add this: Reviewed-by: Alex Elder Thank you fore reviewing this patch! $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) . . . diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 83b38ae8908c..56bf1a4f95ad 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, goto exit; /* update ucontrol */ - if (gbvalue.value.integer_value[0] != val) { + if (gbvalue.value.integer_value[0] != cpu_to_le32(val)) { It's equivalent, but I have a small preference to convert the value from gbvalue into CPU byte order rather than what you have here. Thank you for the suggestion! I'll use CPU byte order when submitting next version. for (wi = 0; wi < wlist->num_widgets; wi++) { widget = wlist->widgets[wi]; snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, @@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_to_cpu(ctl->data_cport); - ctldata->access = ctl->access; + ctldata->access = le32_to_cpu(ctl->access); ctldata->vcount = ctl->count_values; ctldata->info = >info; *kctl = (struct snd_kcontrol_new) @@ -744,10 +744,10 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol, return ret; } - ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0]; + ucontrol->value.enumerated.item[0] = le32_to_cpu(gbvalue.value.enumerated_item[0]); if (e->shift_l != e->shift_r) ucontrol->value.enumerated.item[1] = - gbvalue.value.enumerated_item[1]; + le32_to_cpu(gbvalue.value.enumerated_item[1]); return 0; } @@ -801,10 +801,10 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, mask = e->mask << e->shift_l; if (gbvalue.value.enumerated_item[0] != - ucontrol->value.enumerated.item[0]) { + cpu_to_le32(ucontrol->value.enumerated.item[0])) { change = 1; gbvalue.value.enumerated_item[0] = - ucontrol->value.enumerated.item[0]; + cpu_to_le32(ucontrol->value.enumerated.item[0]); } if (e->shift_l != e->shift_r) { @@ -813,10 +813,10 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol, val |= ucontrol->value.enumerated.item[1] << e->shift_r; mask |= e->mask << e->shift_r; if (gbvalue.value.enumerated_item[1] != - ucontrol->value.enumerated.item[1]) { + cpu_to_le32(ucontrol->value.enumerated.item[1])) { change = 1; gbvalue.value.enumerated_item[1] = - ucontrol->value.enumerated.item[1]; + cpu_to_le32(ucontrol->value.enumerated.item[1]); } } @@ -887,7 +887,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_to_cpu(ctl->data_cport); - ctldata->access = ctl->access; + ctldata->access = le32_to_cpu(ctl->access); ctldata->vcount = ctl->count_values; ctldata->info = >info; *kctl = (struct snd_kcontrol_new) -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t
On Thu, Sep 24, 2020 at 01:00:57PM +0200, Greg Kroah-Hartman wrote: On Thu, Sep 24, 2020 at 06:20:39PM +0800, Coiby Xu wrote: Use __8 to replace int and remove the unnecessary __bitwise type attribute. Found by sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted snd_ctl_elem_type_t drivers/staging/greybus/audio_topology.c:679:14: warning: restricted snd_ctl_elem_iface_t degrades to integer drivers/staging/greybus/audio_topology.c:906:14: warning: restricted snd_ctl_elem_iface_t degrades to integer Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_topology.c | 2 +- include/uapi/sound/asound.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 56bf1a4f95ad..f6023ff390c2 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, /* update uinfo */ uinfo->access = data->access; uinfo->count = data->vcount; - uinfo->type = (snd_ctl_elem_type_t)info->type; + uinfo->type = info->type; switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 535a7229e1d9..8e71a95644ab 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -950,7 +950,7 @@ struct snd_ctl_card_info { unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ }; -typedef int __bitwise snd_ctl_elem_type_t; +typedef __u8 snd_ctl_elem_type_t; #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 0) /* invalid */ #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ @@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t; #defineSNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ #defineSNDRV_CTL_ELEM_TYPE_LASTSNDRV_CTL_ELEM_TYPE_INTEGER64 -typedef int __bitwise snd_ctl_elem_iface_t; +typedef __u8 snd_ctl_elem_iface_t; #defineSNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ #defineSNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ #defineSNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ I can't take a uapi sound header file patch along with a driver change, these need to be independant. Thank you and Alex for reminding me this is a change of public header! And this is a userspace api, you just changed the size of an externally facing variable, are you _SURE_ that is ok to do? The reasons I make this change are, 1) using int to represent 7 enumeration values seems to be overkill; 2) using one type could avoid worries about byte order. I examine one userspace example (libalsa-intf/alsa_mixer.c [1]). This change won't cause compiling breakage. But I don't the experience to imagine any other bad consequence. Another way to avoid userspace API change is to let "struct gb_audio_ctl_elem_info" use snd_ctl_elem_iface_t type which may be more elegant than using "__force" as suggested by Alex, $ git diff diff --git a/include/linux/greybus/greybus_protocols.h b/include/linux/greybus/greybus_protocols.h index aeb8f9243545..7f6753ec7ef7 100644 --- a/include/linux/greybus/greybus_protocols.h +++ b/include/linux/greybus/greybus_protocols.h @@ -8,6 +8,7 @@ #define __GREYBUS_PROTOCOLS_H #include +#include /* Fixed IDs for control/svc protocols */ @@ -1997,7 +1998,7 @@ struct gb_audio_enumerated { } __packed; struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux source */ - __u8type; /* GB_AUDIO_CTL_ELEM_TYPE_* */ + snd_ctl_elem_type_t type; /* GB_AUDIO_CTL_ELEM_TYPE_* */ __le16 dimen[4]; union { struct gb_audio_integer integer My only concern is if greybus authors have any special reason to not include sound/asound.h in the first place and re-define things like SNDRV_CTL_ELEM_TYPE_*, /* See SNDRV_CTL_ELEM_TYPE_* in Linux source */ #define GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN 0x01 #define GB_AUDIO_CTL_ELEM_TYPE_INTEGER 0x02 /* See SNDRV_CTL_ELEM_IFACE_* in Linux source */ #define GB_AUDIO_CTL_ELEM_IFACE_CARD0x00 ... /* SNDRV_CTL_ELEM_ACCESS_* in Linux source */ #define GB_AUDIO_ACCESS_READBIT(0) ... [1] https://gitlab.com/Codeaurora/platform_hardware_qcom_audio/-/blob/aee603
[PATCH 3/3] [PATCH] staging: greybus: __u8 is sufficient for snd_ctl_elem_type_t and snd_ctl_elem_iface_t
Use __8 to replace int and remove the unnecessary __bitwise type attribute. Found by sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_topology.c:185:24: warning: cast to restricted snd_ctl_elem_type_t drivers/staging/greybus/audio_topology.c:679:14: warning: restricted snd_ctl_elem_iface_t degrades to integer drivers/staging/greybus/audio_topology.c:906:14: warning: restricted snd_ctl_elem_iface_t degrades to integer Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_topology.c | 2 +- include/uapi/sound/asound.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 56bf1a4f95ad..f6023ff390c2 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -182,7 +182,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol, /* update uinfo */ uinfo->access = data->access; uinfo->count = data->vcount; - uinfo->type = (snd_ctl_elem_type_t)info->type; + uinfo->type = info->type; switch (info->type) { case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN: diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 535a7229e1d9..8e71a95644ab 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -950,7 +950,7 @@ struct snd_ctl_card_info { unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ }; -typedef int __bitwise snd_ctl_elem_type_t; +typedef __u8 snd_ctl_elem_type_t; #defineSNDRV_CTL_ELEM_TYPE_NONE((__force snd_ctl_elem_type_t) 0) /* invalid */ #defineSNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ #defineSNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ @@ -960,7 +960,7 @@ typedef int __bitwise snd_ctl_elem_type_t; #defineSNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ #defineSNDRV_CTL_ELEM_TYPE_LASTSNDRV_CTL_ELEM_TYPE_INTEGER64 -typedef int __bitwise snd_ctl_elem_iface_t; +typedef __u8 snd_ctl_elem_iface_t; #defineSNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ #defineSNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ #defineSNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/3] staging: greybus: codecs: use SNDRV_PCM_FMTBIT_S16_LE for format bitmask
snd_soc_pcm_stream.formats should use the bitmask SNDRV_PCM_FMTBIT_* instead of the sequential integers SNDRV_PCM_FORMAT_* as explained by commit e712bfca1ac1f63f622f87c2f33b57608f2a4d19 ("ASoC: codecs: use SNDRV_PCM_FMTBIT_* for format bitmask"). Found by sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:691:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:701:36:got restricted snd_pcm_format_t [usertype] Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 74538f8c5fa4..494aa823e998 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .playback = { .stream_name = "I2S 0 Playback", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .capture = { .stream_name = "I2S 0 Capture", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, -- 2.28.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/3] [PATCH] staging: greybus: fix warnings about endianness detected by sparse
This patch fix the following warnings from sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 [usertype] access drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32 drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32 drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32 drivers/staging/greybus/audio_topology.c:805:50:got unsigned int drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32 drivers/staging/greybus/audio_topology.c:817:58:got unsigned int drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 [usertype] access Suggested-by: Dan Carpenter Reviewed-by: Dan Carpenter Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_module.c | 6 +++--- drivers/staging/greybus/audio_topology.c | 18 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 16f60256adb2..c52c4f361b90 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, greybus_set_drvdata(bundle, gbmodule); dai->id = 0; - dai->data_cport = connection->intf_cport_id; + dai->data_cport = cpu_to_le16(connection->intf_cport_id); dai->connection = connection; list_add(>list, >data_list); @@ -329,7 +329,7 @@ static int gb_audio_probe(struct gb_bundle *bundle, if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); goto disable_data_connection; } } @@ -451,7 +451,7 @@ static int gb_audio_resume(struct device *dev) if (ret) { dev_err(dev, "%d:Error while enabling %d:data connection\n", - ret, dai->data_cport); + ret, le16_to_cpu(dai->data_cport)); return ret; } } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index 83b38ae8908c..56bf1a4f95ad 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -466,7 +466,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, goto exit; /* update ucontrol */ - if (gbvalue.value.integer_value[0] != val) { + if (gbvalue.value.integer_value[0] != cpu_to_le32(val)) { for (wi = 0; wi < wlist->num_widgets; wi++) { widget = wlist->widgets[wi]; snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, @@ -689,7 +689,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb, return -ENOMEM; ctldata->ctl_id = ctl->id; ctldata->data_cport = le16_t
Re: [PATCH] staging: greybus: fix warnings detected by sparse
On Mon, Aug 24, 2020 at 12:41:48PM +0300, Dan Carpenter wrote: On Mon, Aug 24, 2020 at 10:50:59AM +0800, Coiby Xu wrote: This patch fix the following warnings from sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:691:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:701:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 [usertype] access drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32 drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32 drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32 drivers/staging/greybus/audio_topology.c:805:50:got unsigned int drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32 drivers/staging/greybus/audio_topology.c:817:58:got unsigned int drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 [usertype] access Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_codec.c| 4 ++-- drivers/staging/greybus/audio_module.c | 2 +- drivers/staging/greybus/audio_topology.c | 18 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 74538f8c5fa4..494aa823e998 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .playback = { .stream_name = "I2S 0 Playback", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .capture = { .stream_name = "I2S 0 Capture", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, These changes need to be explained better. We're changing formats from 2 to 1 << 2. When you're writing commit messages, please imagine me as the target audience. I have a fairly decent understanding of the kernel and C, but I don't know very much about the sound subsystem. (Sorry for the late reply! I didn't notice my email client failed to delivered this email.) Thank you for showing me SNDRV_PCM_FORMAT_S16_LE != SNDRV_PCM_FMTBIT_S16_LE. I thought they only differ in type so no domain knowledge is needed. This code used to work, right? How was i
Re: [PATCH v3] staging: qlge: fix build breakage with dumping enabled
On Thu, Sep 03, 2020 at 12:49:18PM +0900, Benjamin Poirier wrote: On 2020-09-02 22:00 +0800, Coiby Xu wrote: This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \ QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- Thanks for following up on this issue. [...] @@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { - if (!tx_ring) - return; + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "= Dumping tx_ring %d ===\n", tx_ring->wq_id); netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base); Did you actually check to confirm that the test can be removed? Thank you for the reminding! For the current code, when ql_dump_tx_ring is called, tx_ring would never be null. This is something that you should mention in the changelog at the very least since that change is not directly about fixing the build breakage and if it's wrong, it can lead to null pointer deref. I thought it is common practice in C that the caller makes sure the passed parameter isn't a null pointer because a QEMU developer also gave me the same advice after reviewing one of my patches for QEMU a few weeks ago. I'll mention this in the commit message. Thank you for the suggestion! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] staging: qlge: fix build breakage with dumping enabled
On Thu, Aug 27, 2020 at 09:50:10AM +0900, Benjamin Poirier wrote: On 2020-08-27 07:27 +0800, Coiby Xu wrote: This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \ QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 20 ++-- drivers/staging/qlge/qlge_dbg.c | 24 ++-- drivers/staging/qlge/qlge_main.c | 8 3 files changed, 32 insertions(+), 20 deletions(-) [...] @@ -1632,6 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { + struct ql_adapter *qdev = tx_ring->qdev; + if (!tx_ring) return; Given the null check for tx_ring, it seems unwise to dereference tx_ring before the check. Looking at ql_dump_all(), I'm not sure that the check is needed at all though. Maybe it should be removed. Same problem in ql_dump_rx_ring(). Thank you for the spotting this issue! I'll remove the check. netdev_err(qdev->ndev, "= Dumping tx_ring %d ===\n", @@ -1657,6 +1662,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) void ql_dump_ricb(struct ricb *ricb) { int i; + struct ql_adapter *qdev = + container_of(ricb, struct ql_adapter, ricb); Here, davem would point out that the variables are not declared in "reverse xmas tree" order. I'll make davem happy then:) -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3] staging: qlge: fix build breakage with dumping enabled
This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \ QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 20 ++-- drivers/staging/qlge/qlge_dbg.c | 28 ++-- drivers/staging/qlge/qlge_main.c | 8 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 483ce04789ed..7f6798b223ef 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2338,21 +2338,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #endif #ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) #else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) #endif #ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) #else -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) #endif #ifdef QL_ALL_DUMP diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index a55bf0b3e9dc..e139e15516fa 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) } if (value) netdev_err(qdev->ndev, - "%s: Routing Mask %d = 0x%.08x\n", + "Routing Mask %d = 0x%.08x\n", i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); @@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev) #ifdef QL_CB_DUMP void ql_dump_wqicb(struct wqicb *wqicb) { + struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); netdev_err(qdev->ndev, "wqicb->flags = %x\n", @@ -1632,8 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { - if (!tx_ring) - return; + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "= Dumping tx_ring %d ===\n", tx_ring->wq_id); netdev_err(qdev->ndev, "tx_ring->base = %p\n", tx_ring->wq_base); @@ -1656,6
[PATCH v2] staging: qlge: fix build breakage with dumping enabled
This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage of missing `struct ql_adapter *qdev` for some functions and a warning of type mismatch with dumping enabled, i.e., $ make CFLAGS_MODULE="QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 \ QL_IB_DUMP=1 QL_REG_DUMP=1 QL_DEV_DUMP=1" M=drivers/staging/qlge qlge_dbg.c: In function ‘ql_dump_ob_mac_rsp’: qlge_dbg.c:2051:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 2051 | netdev_err(qdev->ndev, "%s\n", __func__); | ^~~~ qlge_dbg.c: In function ‘ql_dump_routing_entries’: qlge_dbg.c:1435:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ~^ | | | char * | %d 1436 |i, value); |~ || |int qlge_dbg.c:1435:37: warning: format ‘%x’ expects a matching ‘unsigned int’ argument [-Wformat=] 1435 |"%s: Routing Mask %d = 0x%.08x\n", | ^ | | | unsigned int Fixes: 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Suggested-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 20 ++-- drivers/staging/qlge/qlge_dbg.c | 24 ++-- drivers/staging/qlge/qlge_main.c | 8 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 483ce04789ed..7f6798b223ef 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2338,21 +2338,21 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); #endif #ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) +void ql_dump_tx_desc(struct ql_adapter *qdev, struct tx_buf_desc *tbd); +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) #else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) #endif #ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) +void ql_dump_ib_mac_rsp(struct ql_adapter *qdev, struct ib_mac_iocb_rsp *ib_mac_rsp); +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) ql_dump_ib_mac_rsp(qdev, ib_mac_rsp) #else -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) +#define QL_DUMP_IB_MAC_RSP(qdev, ib_mac_rsp) #endif #ifdef QL_ALL_DUMP diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index a55bf0b3e9dc..e62ee4e2f118 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) } if (value) netdev_err(qdev->ndev, - "%s: Routing Mask %d = 0x%.08x\n", + "Routing Mask %d = 0x%.08x\n", i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); @@ -1617,6 +1617,9 @@ void ql_dump_qdev(struct ql_adapter *qdev) #ifdef QL_CB_DUMP void ql_dump_wqicb(struct wqicb *wqicb) { + struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); + struct ql_adapter *qdev = tx_ring->qdev; + netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); netdev_err(qdev->ndev, "wqicb->flags = %x\n", @@ -1632,6 +1635,8 @@ void ql_dump_wqicb(struct wqicb *wqicb) void ql_dump_tx_ring(struct tx_ring *tx_ring) { + struct ql_adapter *qdev = tx_ring->qdev; + if (!tx_ring) return; netdev_err(qdev->ndev, "= Dumping tx_ring %d ===\n", @@ -1657,6 +1662,8 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) void ql_dump_ricb(struct ricb *ricb) { int i; + struct ql_adapter *q
Re: [PATCH] staging: qlge: fix build breakage with dumping enabled
On Fri, Aug 21, 2020 at 05:31:59PM +0900, Benjamin Poirier wrote: On 2020-08-21 15:03 +0800, Coiby Xu wrote: This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage with dumping enabled, i.e., $ QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 QL_REG_DUMP=1 \ QL_IB_DUMP=1 QL_DEV_DUMP=1 make M=drivers/staging/qlge Fixes: 0107635e15ac ("taging: qlge: replace pr_err with netdev_err") ^ staging Thank you for reminding me of the typo! Reported-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 42 drivers/staging/qlge/qlge_dbg.c | 36 +-- drivers/staging/qlge/qlge_main.c | 4 +-- 3 files changed, 41 insertions(+), 41 deletions(-) [...] @@ -1615,7 +1615,7 @@ void ql_dump_qdev(struct ql_adapter *qdev) #endif #ifdef QL_CB_DUMP -void ql_dump_wqicb(struct wqicb *wqicb) +void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb) { This can be fixed without adding another argument: struct tx_ring *tx_ring = container_of(wqicb, struct tx_ring, wqicb); struct ql_adapter *qdev = tx_ring->qdev; netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); @@ -1630,7 +1630,7 @@ void ql_dump_wqicb(struct wqicb *wqicb) (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr)); } -void ql_dump_tx_ring(struct tx_ring *tx_ring) +void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring) { This can be fixed without adding another argument: struct ql_adapter *qdev; if (!tx_ring) return; qdev = tx_ring->qdev; ... similar comment for the other instances. Thank you for the simpler solution! For QL_OB_DUMP and QL_IB_DUMP, `struct ql_adapter *qdev` can't be obtained via container_of. So qdev are still directly passed to these functions. -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: greybus: fix warnings detected by sparse
This patch fix the following warnings from sparse, $ make C=2 drivers/staging/greybus/ drivers/staging/greybus/audio_codec.c:691:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:691:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:691:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_codec.c:701:36: warning: incorrect type in initializer (different base types) drivers/staging/greybus/audio_codec.c:701:36:expected unsigned long long [usertype] formats drivers/staging/greybus/audio_codec.c:701:36:got restricted snd_pcm_format_t [usertype] drivers/staging/greybus/audio_module.c:222:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_module.c:222:25:expected restricted __le16 [usertype] data_cport drivers/staging/greybus/audio_module.c:222:25:got unsigned short [usertype] intf_cport_id drivers/staging/greybus/audio_topology.c:460:40: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:691:41: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:691:41:expected unsigned int access drivers/staging/greybus/audio_topology.c:691:41:got restricted __le32 [usertype] access drivers/staging/greybus/audio_topology.c:746:44: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:746:44:expected unsigned int drivers/staging/greybus/audio_topology.c:746:44:got restricted __le32 drivers/staging/greybus/audio_topology.c:748:52: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:748:52:expected unsigned int drivers/staging/greybus/audio_topology.c:748:52:got restricted __le32 drivers/staging/greybus/audio_topology.c:802:42: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:805:50: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:805:50:expected restricted __le32 drivers/staging/greybus/audio_topology.c:805:50:got unsigned int drivers/staging/greybus/audio_topology.c:814:50: warning: restricted __le32 degrades to integer drivers/staging/greybus/audio_topology.c:817:58: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:817:58:expected restricted __le32 drivers/staging/greybus/audio_topology.c:817:58:got unsigned int drivers/staging/greybus/audio_topology.c:889:25: warning: incorrect type in assignment (different base types) drivers/staging/greybus/audio_topology.c:889:25:expected unsigned int access drivers/staging/greybus/audio_topology.c:889:25:got restricted __le32 [usertype] access Signed-off-by: Coiby Xu --- drivers/staging/greybus/audio_codec.c| 4 ++-- drivers/staging/greybus/audio_module.c | 2 +- drivers/staging/greybus/audio_topology.c | 18 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 74538f8c5fa4..494aa823e998 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -688,7 +688,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .playback = { .stream_name = "I2S 0 Playback", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, @@ -698,7 +698,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = { .capture = { .stream_name = "I2S 0 Capture", .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE, .rate_max = 48000, .rate_min = 48000, .channels_min = 1, diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index 16f60256adb2..00848b84b022 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -219,7 +219,7 @@ static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule, greybus_set_drvdata(bundle, gbmodule); dai->id = 0; - dai->data_cport = connection->intf_cport_id; + dai->data_cport = cpu_to_le16(connection->intf_cport_id); dai->connection = connection; list_add(>list, >data_list); diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging
[PATCH] staging: qlge: fix build breakage with dumping enabled
This fixes commit 0107635e15ac ("staging: qlge: replace pr_err with netdev_err") which introduced an build breakage with dumping enabled, i.e., $ QL_ALL_DUMP=1 QL_OB_DUMP=1 QL_CB_DUMP=1 QL_REG_DUMP=1 \ QL_IB_DUMP=1 QL_DEV_DUMP=1 make M=drivers/staging/qlge Fixes: 0107635e15ac ("taging: qlge: replace pr_err with netdev_err") Reported-by: Benjamin Poirier Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 42 drivers/staging/qlge/qlge_dbg.c | 36 +-- drivers/staging/qlge/qlge_main.c | 4 +-- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 483ce04789ed..c72c1d2a00a8 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2315,37 +2315,37 @@ void ql_dump_qdev(struct ql_adapter *qdev); #endif #ifdef QL_CB_DUMP -void ql_dump_wqicb(struct wqicb *wqicb); -void ql_dump_tx_ring(struct tx_ring *tx_ring); -void ql_dump_ricb(struct ricb *ricb); -void ql_dump_cqicb(struct cqicb *cqicb); -void ql_dump_rx_ring(struct rx_ring *rx_ring); +void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb); +void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring); +void ql_dump_ricb(struct ql_adapter *qdev, struct ricb *ricb); +void ql_dump_cqicb(struct ql_adapter *qdev, struct cqicb *cqicb); +void ql_dump_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring); void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring) +#define QL_DUMP_RICB(qdev, ricb) ql_dump_ricb(qdev, ricb) +#define QL_DUMP_WQICB(qdev, wqicb) ql_dump_wqicb(qdev, wqicb) +#define QL_DUMP_TX_RING(qdev, tx_ring) ql_dump_tx_ring(qdev, tx_ring) +#define QL_DUMP_CQICB(qdev, cqicb) ql_dump_cqicb(qdev, cqicb) +#define QL_DUMP_RX_RING(qdev, rx_ring) ql_dump_rx_ring(qdev, rx_ring) #define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ ql_dump_hw_cb(qdev, size, bit, q_id) #else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) +#define QL_DUMP_RICB(qdev, ricb) +#define QL_DUMP_WQICB(qdev, wqicb) +#define QL_DUMP_TX_RING(qdev, tx_ring) +#define QL_DUMP_CQICB(qdev, cqicb) +#define QL_DUMP_RX_RING(qdev, rx_ring) #define QL_DUMP_HW_CB(qdev, size, bit, q_id) #endif #ifdef QL_OB_DUMP void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) +void ql_dump_ob_mac_iocb(struct ql_adapter *qdev, struct ob_mac_iocb_req *ob_mac_iocb); +void ql_dump_ob_mac_rsp(struct ql_adapter *qdev, struct ob_mac_iocb_rsp *ob_mac_rsp); +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) ql_dump_ob_mac_iocb(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) ql_dump_ob_mac_rsp(qdev, ob_mac_rsp) #else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) +#define QL_DUMP_OB_MAC_IOCB(qdev, ob_mac_iocb) +#define QL_DUMP_OB_MAC_RSP(qdev, ob_mac_rsp) #endif #ifdef QL_IB_DUMP diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index a55bf0b3e9dc..123d3f7475ae 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1431,7 +1431,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) } if (value) netdev_err(qdev->ndev, - "%s: Routing Mask %d = 0x%.08x\n", + "Routing Mask %d = 0x%.08x\n", i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); @@ -1615,7 +1615,7 @@ void ql_dump_qdev(struct ql_adapter *qdev) #endif #ifdef QL_CB_DUMP -void ql_dump_wqicb(struct wqicb *wqicb) +void ql_dump_wqicb(struct ql_adapter *qdev, struct wqicb *wqicb) { netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); netdev_err(qdev->ndev, "wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); @@ -1630,7 +1630,7 @@ void ql_dump_wqicb(struct wqicb *wqicb) (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr)); } -void ql_dump_tx_ring(struct tx_ring *tx_ring) +void ql_dump_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring) { if (!tx_ring) return; @@ -1654,7 +1654,7 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring) netdev_err(qdev->ndev, "tx_ring-
Re: [RFC 3/3] staging: qlge: clean up code that dump info to dmesg
On Sun, Aug 16, 2020 at 11:57:17AM +0900, Benjamin Poirier wrote: On 2020-08-15 00:06 +0800, Coiby Xu wrote: The related code are not necessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. I would suggest to add the drgn script from the cover letter to Documentation/networking/device_drivers/qlogic/ Thank you for this suggestion! I planned to send a pull request to https://github.com/osandov/drgn. This is a better idea. I would also suggest to submit a separate patch now which fixes the build breakage reported in <20200629053004.GA6165@f3> while you work on removing that code. I'll send a single patch to fix that issue before preparing for v1 of this work. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 672 drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 6 - 4 files changed, 761 deletions(-) [...] diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 058889687907..368394123d16 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1326,675 +1326,3 @@ void ql_mpi_core_to_log(struct work_struct *work) sizeof(*qdev->mpi_coredump), false); } -#ifdef QL_REG_DUMP -static void ql_dump_intr_states(struct ql_adapter *qdev) -{ [...] - } -} -#endif This leaves a stray newline at the end of the file and also does not apply over latest staging. I will fix it in v1. Thank you for reviewing this patch! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [RFC 1/3] Initialize devlink health dump framework for the dlge driver
On Sun, Aug 16, 2020 at 11:56:40AM +0900, Benjamin Poirier wrote: On 2020-08-15 00:05 +0800, Coiby Xu wrote: Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h| 9 +++ drivers/staging/qlge/qlge_health.c | 43 ++ drivers/staging/qlge/qlge_health.h | 2 ++ drivers/staging/qlge/qlge_main.c | 21 +++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_health.c create mode 100644 drivers/staging/qlge/qlge_health.h diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..0a1e4c8dd546 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index fc8c5ca8935d..055ded6dab60 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2061,6 +2061,14 @@ struct nic_operations { int (*port_initialize) (struct ql_adapter *); }; This patch doesn't apply over the latest staging tree. I think your tree is missing commit d923bb6bf508 ("staging: qlge: qlge.h: Function definition arguments should have names.") Thank you for applying the patch to test it! I had incorrect understanding about the word "RFC" and didn't do a rebase onto the latest staging tree. + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; I don't have experience implementing devlink callbacks but looking at some other devlink users (mlx4, ionic, ice), all of them use devlink priv space for their main private structure. That would be struct ql_adapter in this case. Is there a good reason to stray from that pattern? +struct devlink_health_reporter *reporter; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2078,6 +2086,7 @@ struct ql_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct qlge_devlink *devlink; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_health.c b/drivers/staging/qlge/qlge_health.c new file mode 100644 index ..292f6b1827e1 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.c @@ -0,0 +1,43 @@ +#include "qlge.h" +#include "qlge_health.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; I think select NET_DEVLINK should be added to drivers/staging/qlge/Kconfig Thank you for reminding me! + +int qlge_health_create_reporters(struct qlge_devlink *priv) +{ + int err; + + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, + priv); + if (IS_ERR(reporter)) { + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); + return PTR_ERR(reporter); + } + priv->reporter = reporter; + + if (err) + return err; + + return 0; +} + + Stray newlines Will fix it in v1. diff --git a/drivers/staging/qlge/qlge_health.h b/drivers/staging/qlge/qlge_health.h new file mode 100644 index ..07d3bafab845 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.h @@ -0,0 +1,2 @@ +#include +int qlge_health_create_reporters(struct qlge_devlink *priv); I would suggest to put this in qlge.h instead of creating a new file. Although there are only two lines for now, is it possible qlge will add more devlink code? If that's the case, a file to single out these code is necessary as is the same to some other drivers, $ find drivers -name *health*.h drivers/net/ethernet/mellanox/mlx5/core/en/health.h $ find drivers -name *devlink*.h drivers/net/ethernet/huawei/hinic/hinic_devlink.h drivers/net/ethernet/mellanox/mlx5/core/devlink.h drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h drivers/net/ethernet/intel/ice/ice_devlink.h
[RFC 3/3] staging: qlge: clean up code that dump info to dmesg
The related code are not necessary because, - Device status and general registers can be obtained by ethtool. - Coredump can be done via devlink health reporter. - Structure related to the hardware (struct ql_adapter) can be obtained by crash or drgn. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge.h | 82 drivers/staging/qlge/qlge_dbg.c | 672 drivers/staging/qlge/qlge_ethtool.c | 1 - drivers/staging/qlge/qlge_main.c| 6 - 4 files changed, 761 deletions(-) diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index 055ded6dab60..8ed81ae0f9d8 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2288,86 +2288,4 @@ void ql_check_lb_frame(struct ql_adapter *, struct sk_buff *); int ql_own_firmware(struct ql_adapter *qdev); int ql_clean_lb_rx_ring(struct rx_ring *rx_ring, int budget); -/* #define QL_ALL_DUMP */ -/* #define QL_REG_DUMP */ -/* #define QL_DEV_DUMP */ -/* #define QL_CB_DUMP */ -/* #define QL_IB_DUMP */ -/* #define QL_OB_DUMP */ - -#ifdef QL_REG_DUMP -void ql_dump_xgmac_control_regs(struct ql_adapter *qdev); -void ql_dump_routing_entries(struct ql_adapter *qdev); -void ql_dump_regs(struct ql_adapter *qdev); -#define QL_DUMP_REGS(qdev) ql_dump_regs(qdev) -#define QL_DUMP_ROUTE(qdev) ql_dump_routing_entries(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) ql_dump_xgmac_control_regs(qdev) -#else -#define QL_DUMP_REGS(qdev) -#define QL_DUMP_ROUTE(qdev) -#define QL_DUMP_XGMAC_CONTROL_REGS(qdev) -#endif - -#ifdef QL_STAT_DUMP -void ql_dump_stat(struct ql_adapter *qdev); -#define QL_DUMP_STAT(qdev) ql_dump_stat(qdev) -#else -#define QL_DUMP_STAT(qdev) -#endif - -#ifdef QL_DEV_DUMP -void ql_dump_qdev(struct ql_adapter *qdev); -#define QL_DUMP_QDEV(qdev) ql_dump_qdev(qdev) -#else -#define QL_DUMP_QDEV(qdev) -#endif - -#ifdef QL_CB_DUMP -void ql_dump_wqicb(struct wqicb *wqicb); -void ql_dump_tx_ring(struct tx_ring *tx_ring); -void ql_dump_ricb(struct ricb *ricb); -void ql_dump_cqicb(struct cqicb *cqicb); -void ql_dump_rx_ring(struct rx_ring *rx_ring); -void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id); -#define QL_DUMP_RICB(ricb) ql_dump_ricb(ricb) -#define QL_DUMP_WQICB(wqicb) ql_dump_wqicb(wqicb) -#define QL_DUMP_TX_RING(tx_ring) ql_dump_tx_ring(tx_ring) -#define QL_DUMP_CQICB(cqicb) ql_dump_cqicb(cqicb) -#define QL_DUMP_RX_RING(rx_ring) ql_dump_rx_ring(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) \ - ql_dump_hw_cb(qdev, size, bit, q_id) -#else -#define QL_DUMP_RICB(ricb) -#define QL_DUMP_WQICB(wqicb) -#define QL_DUMP_TX_RING(tx_ring) -#define QL_DUMP_CQICB(cqicb) -#define QL_DUMP_RX_RING(rx_ring) -#define QL_DUMP_HW_CB(qdev, size, bit, q_id) -#endif - -#ifdef QL_OB_DUMP -void ql_dump_tx_desc(struct tx_buf_desc *tbd); -void ql_dump_ob_mac_iocb(struct ob_mac_iocb_req *ob_mac_iocb); -void ql_dump_ob_mac_rsp(struct ob_mac_iocb_rsp *ob_mac_rsp); -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) ql_dump_ob_mac_iocb(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) ql_dump_ob_mac_rsp(ob_mac_rsp) -#else -#define QL_DUMP_OB_MAC_IOCB(ob_mac_iocb) -#define QL_DUMP_OB_MAC_RSP(ob_mac_rsp) -#endif - -#ifdef QL_IB_DUMP -void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp); -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) ql_dump_ib_mac_rsp(ib_mac_rsp) -#else -#define QL_DUMP_IB_MAC_RSP(ib_mac_rsp) -#endif - -#ifdef QL_ALL_DUMP -void ql_dump_all(struct ql_adapter *qdev); -#define QL_DUMP_ALL(qdev) ql_dump_all(qdev) -#else -#define QL_DUMP_ALL(qdev) -#endif - #endif /* _QLGE_H_ */ diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 058889687907..368394123d16 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1326,675 +1326,3 @@ void ql_mpi_core_to_log(struct work_struct *work) sizeof(*qdev->mpi_coredump), false); } -#ifdef QL_REG_DUMP -static void ql_dump_intr_states(struct ql_adapter *qdev) -{ - int i; - u32 value; - - for (i = 0; i < qdev->intr_count; i++) { - ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask); - value = ql_read32(qdev, INTR_EN); - pr_err("%s: Interrupt %d is %s\n", - qdev->ndev->name, i, - (value & INTR_EN_EN ? "enabled" : "disabled")); - } -} - -#define DUMP_XGMAC(qdev, reg) \ -do { \ - u32 data; \ - ql_read_xgmac_reg(qdev, reg, );\ - pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \ -} while (0) - -void ql_dump_xgmac_control_regs(struct ql_adapter *qdev) -{ - if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) { - pr_err("%s: Couldn't get xgmac sem\n", _
[RFC 2/3] staging: qlge: coredump via devlink health reporter
$ devlink health dump show DEVICE reporter coredump -p -j { "Core Registers": { "segment": 1, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "Test Logic Regs": { "segment": 2, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, "RMII Registers": { "segment": 3, "values": [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ] }, ... "Sem Registers": { "segment": 50, "values": [ 0,0,0,0 ] } } Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_health.c | 125 +++-- 1 file changed, 119 insertions(+), 6 deletions(-) diff --git a/drivers/staging/qlge/qlge_health.c b/drivers/staging/qlge/qlge_health.c index 292f6b1827e1..a146cca6a3dc 100644 --- a/drivers/staging/qlge/qlge_health.c +++ b/drivers/staging/qlge/qlge_health.c @@ -1,16 +1,129 @@ #include "qlge.h" #include "qlge_health.h" -static int -qlge_reporter_coredump(struct devlink_health_reporter *reporter, - struct devlink_fmsg *fmsg, void *priv_ctx, - struct netlink_ext_ack *extack) +static int fill_seg_(struct devlink_fmsg *fmsg, + struct mpi_coredump_segment_header *seg_header, + u32 *reg_data) { - return 0; + int i; + int header_size = sizeof(struct mpi_coredump_segment_header); + int regs_num = (seg_header->seg_size - header_size) / sizeof(u32); + int err; + + err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); + if (err) + return err; + err = devlink_fmsg_obj_nest_start(fmsg); + if (err) + return err; + err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); + if (err) + return err; + for (i = 0; i < regs_num; i++) { + err = devlink_fmsg_u32_put(fmsg, *reg_data); + if (err) + return err; + reg_data++; + } + err = devlink_fmsg_obj_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_arr_pair_nest_end(fmsg); + if (err) + return err; + err = devlink_fmsg_pair_nest_end(fmsg); + return err; +} + +#define fill_seg(seg_hdr, seg_regs) \ + err = fill_seg_(fmsg, >seg_hdr, dump->seg_regs); \ + if (err) { \ + kvfree(dump); \ + return err;\ + } + +static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + int err = 0; + + struct qlge_devlink *dev = devlink_health_reporter_priv(reporter); + struct ql_adapter *qdev = dev->qdev; + struct ql_mpi_coredump *dump = kvmalloc(sizeof(struct ql_mpi_coredump), + GFP_KERNEL); + if (!dump) + return -ENOMEM; + + err = ql_core_dump(qdev, dump); + if (err) { + kvfree(dump); + return err; + } + + fill_seg(core_regs_seg_hdr, mpi_core_regs); + fill_seg(test_logic_regs_seg_hdr, test_logic_regs); + fill_seg(rmii_regs_seg_hdr, rmii_regs); + fill_seg(fcmac1_regs_seg_hdr, fcmac1_regs); + fill_seg(fcmac2_regs_seg_hdr, fcmac2_regs); + fill_seg(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); + fill_seg(ide_regs_seg_hdr, ide_regs); + fill_seg(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); + fill_seg(smbus_regs_seg_hdr, smbus_regs); + fill_seg(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); + fill_seg(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); + fill_seg(i2c_regs_seg_hdr, i2c_regs); + fill_seg(memc_regs_seg_hdr, memc_regs); + fill_seg(pbus_regs_seg_hdr, pbus_regs); + fill_seg(mde_regs_seg_hdr, mde_regs); + fill_seg(nic_regs_seg_hdr, nic_regs); + fill_seg(nic2_regs_seg_hdr, nic2_regs); + fill_seg(xgmac1_seg_hdr, xgmac1); + fill_seg(xgmac2_seg_hdr, xgmac2); + fill_seg(code_ram_seg_h
[RFC 1/3] Initialize devlink health dump framework for the dlge driver
Initialize devlink health dump framework for the dlge driver so the coredump could be done via devlink. Signed-off-by: Coiby Xu --- drivers/staging/qlge/Makefile | 2 +- drivers/staging/qlge/qlge.h| 9 +++ drivers/staging/qlge/qlge_health.c | 43 ++ drivers/staging/qlge/qlge_health.h | 2 ++ drivers/staging/qlge/qlge_main.c | 21 +++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/qlge/qlge_health.c create mode 100644 drivers/staging/qlge/qlge_health.h diff --git a/drivers/staging/qlge/Makefile b/drivers/staging/qlge/Makefile index 1dc2568e820c..0a1e4c8dd546 100644 --- a/drivers/staging/qlge/Makefile +++ b/drivers/staging/qlge/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_QLGE) += qlge.o -qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o +qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o qlge_health.o diff --git a/drivers/staging/qlge/qlge.h b/drivers/staging/qlge/qlge.h index fc8c5ca8935d..055ded6dab60 100644 --- a/drivers/staging/qlge/qlge.h +++ b/drivers/staging/qlge/qlge.h @@ -2061,6 +2061,14 @@ struct nic_operations { int (*port_initialize) (struct ql_adapter *); }; + + +struct qlge_devlink { +struct ql_adapter *qdev; +struct net_device *ndev; +struct devlink_health_reporter *reporter; +}; + /* * The main Adapter structure definition. * This structure has all fields relevant to the hardware. @@ -2078,6 +2086,7 @@ struct ql_adapter { struct pci_dev *pdev; struct net_device *ndev;/* Parent NET device */ + struct qlge_devlink *devlink; /* Hardware information */ u32 chip_rev_id; u32 fw_rev_id; diff --git a/drivers/staging/qlge/qlge_health.c b/drivers/staging/qlge/qlge_health.c new file mode 100644 index ..292f6b1827e1 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.c @@ -0,0 +1,43 @@ +#include "qlge.h" +#include "qlge_health.h" + +static int +qlge_reporter_coredump(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg, void *priv_ctx, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static const struct devlink_health_reporter_ops qlge_reporter_ops = { + .name = "dummy", + .dump = qlge_reporter_coredump, +}; + +int qlge_health_create_reporters(struct qlge_devlink *priv) +{ + int err; + + struct devlink_health_reporter *reporter; + struct devlink *devlink; + + devlink = priv_to_devlink(priv); + reporter = + devlink_health_reporter_create(devlink, _reporter_ops, + 0, + priv); + if (IS_ERR(reporter)) { + netdev_warn(priv->ndev, + "Failed to create reporter, err = %ld\n", + PTR_ERR(reporter)); + return PTR_ERR(reporter); + } + priv->reporter = reporter; + + if (err) + return err; + + return 0; +} + + diff --git a/drivers/staging/qlge/qlge_health.h b/drivers/staging/qlge/qlge_health.h new file mode 100644 index ..07d3bafab845 --- /dev/null +++ b/drivers/staging/qlge/qlge_health.h @@ -0,0 +1,2 @@ +#include +int qlge_health_create_reporters(struct qlge_devlink *priv); diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 1650de13842f..b2be7f4b7dd6 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -42,6 +42,7 @@ #include #include "qlge.h" +#include "qlge_health.h" char qlge_driver_name[] = DRV_NAME; const char qlge_driver_version[] = DRV_VERSION; @@ -4550,6 +4551,8 @@ static void ql_timer(struct timer_list *t) mod_timer(>timer, jiffies + (5 * HZ)); } +static const struct devlink_ops qlge_devlink_ops; + static int qlge_probe(struct pci_dev *pdev, const struct pci_device_id *pci_entry) { @@ -4557,6 +4560,13 @@ static int qlge_probe(struct pci_dev *pdev, struct ql_adapter *qdev = NULL; static int cards_found; int err = 0; + struct devlink *devlink; + struct qlge_devlink *qlge_dl; + + devlink = devlink_alloc(_devlink_ops, sizeof(struct qlge_devlink)); + if (!devlink) + return -ENOMEM; + qlge_dl = devlink_priv(devlink); ndev = alloc_etherdev_mq(sizeof(struct ql_adapter), min(MAX_CPUS, @@ -4615,6 +4625,15 @@ static int qlge_probe(struct pci_dev *pdev, free_netdev(ndev); return err; } + + err = devlink_register(devlink, >dev); + if (err) + devlink_free(devlink); + + qlge_health_create_reporters(qlge_dl); + qlge_dl->qdev = qdev; + qlge_dl-&
Re: [PATCH v2 4/4] staging: qlge: replace pr_err with netdev_err
On Mon, Jun 29, 2020 at 02:30:04PM +0900, Benjamin Poirier wrote: On 2020-06-27 22:58 +0800, Coiby Xu wrote: [...] void ql_dump_qdev(struct ql_adapter *qdev) { @@ -1611,99 +1618,100 @@ void ql_dump_qdev(struct ql_adapter *qdev) #ifdef QL_CB_DUMP void ql_dump_wqicb(struct wqicb *wqicb) { - pr_err("Dumping wqicb stuff...\n"); - pr_err("wqicb->len = 0x%x\n", le16_to_cpu(wqicb->len)); - pr_err("wqicb->flags = %x\n", le16_to_cpu(wqicb->flags)); - pr_err("wqicb->cq_id_rss = %d\n", - le16_to_cpu(wqicb->cq_id_rss)); - pr_err("wqicb->rid = 0x%x\n", le16_to_cpu(wqicb->rid)); - pr_err("wqicb->wq_addr = 0x%llx\n", - (unsigned long long)le64_to_cpu(wqicb->addr)); - pr_err("wqicb->wq_cnsmr_idx_addr = 0x%llx\n", - (unsigned long long)le64_to_cpu(wqicb->cnsmr_idx_addr)); + netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); drivers/staging/qlge/qlge_dbg.c:1621:13: error: ‘qdev’ undeclared (first use in this function); did you mean ‘cdev’? 1621 | netdev_err(qdev->ndev, "Dumping wqicb stuff...\n"); | ^~~~ | cdev [...] and many more like that Anyways, qlge_dbg.h is a dumpster. It has hundreds of lines of code bitrotting away in ifdef land. See this comment from David Miller on the topic of ifdef'ed debugging code: https://lore.kernel.org/netdev/20200303.145916.1506066510928020193.da...@davemloft.net/ Thank you for spotting this problem! This issue could be fixed by passing qdev to ql_dump_wqicb. Or are you suggesting we completely remove qlge_dbg since it's only for the purpose of debugging the driver by the developer? Btw, I'm curious how you make this compiling error occur. Do you manually trigger it via "QL_CB_DUMP=1 make M=drivers/staging/qlge" or use some automate tools? -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/4] fix trailing */ in block comment
On Sat, Jun 27, 2020 at 12:47:08PM +0200, Greg Kroah-Hartman wrote: On Sat, Jun 27, 2020 at 06:14:44PM +0800, Coiby Xu wrote: Remove trailing "*/" in block comments. Signed-off-by: Coiby Xu The subject lines of all of your patches should match other patches for this driver. It should look like "staging: qlge: ..." Please fix up and resend a v2 of this series. thanks, greg k-h Thank you for pointing out this issue! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 4/4] staging: qlge: replace pr_err with netdev_err
Replace all pr_errs with netdev_err. Suggested-by: Joe Perches Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 568 1 file changed, 289 insertions(+), 279 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 63e965966ced..32fbd30a6a2e 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -647,7 +647,7 @@ static void ql_get_mac_protocol_registers(struct ql_adapter *qdev, u32 *buf) max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT; break; default: - pr_err("Bad type!!! 0x%08x\n", type); + netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type); max_index = 0; max_offset = 0; break; @@ -1335,9 +1335,8 @@ static void ql_dump_intr_states(struct ql_adapter *qdev) for (i = 0; i < qdev->intr_count; i++) { ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask); value = ql_read32(qdev, INTR_EN); - pr_err("%s: Interrupt %d is %s\n", - qdev->ndev->name, i, - (value & INTR_EN_EN ? "enabled" : "disabled")); + netdev_err(qdev->ndev, "Interrupt %d is %s\n", i, + (value & INTR_EN_EN ? "enabled" : "disabled")); } } @@ -1345,13 +1344,14 @@ static void ql_dump_intr_states(struct ql_adapter *qdev) do { \ u32 data; \ ql_read_xgmac_reg(qdev, reg, );\ - pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \ + netdev_err(qdev->ndev, "%s = 0x%.08x\n", #reg, data); \ } while (0) void ql_dump_xgmac_control_regs(struct ql_adapter *qdev) { if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) { - pr_err("%s: Couldn't get xgmac sem\n", __func__); + netdev_err(qdev->ndev, "%s: Couldn't get xgmac sem\n", + __func__); return; } DUMP_XGMAC(qdev, PAUSE_SRC_LO); @@ -1388,25 +1388,28 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) return; for (i = 0; i < 4; i++) { if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { - pr_err("%s: Failed read of mac index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of mac index register\n", + __func__); break; } if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); + netdev_err(qdev->ndev, + "CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", + i, value[1], value[0], value[2]); } for (i = 0; i < 32; i++) { if (ql_get_mac_addr_reg (qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) { - pr_err("%s: Failed read of mac index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of mac index register\n", + __func__); break; } if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); + netdev_err(qdev->ndev, + "MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } @@ -1422,23 +1425,25 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) for (i = 0; i < 16; i++) { value = 0; if (ql_get_routing_reg(qdev, i, )) { - pr_err("%s: Failed read of routing index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of routing index register\n", +
[PATCH v2 0/4] staging: qlge: coding style fix for the qlge driver
v2 - let all patches' subject lines match the pattern "staging: qlge: ..." These patches fix three coding style problems for all files under drivers/staging/qlge, - trailing */ in block comment - unnecessary else after return or break - pr_err preferred over netdev_err and a bug about releasing lock. Coiby Xu (4): fix trailing */ in block comment fix else after return or break fix ql_sem_unlock replace pr_err with netdev_err drivers/staging/qlge/qlge_dbg.c | 583 --- drivers/staging/qlge/qlge_main.c | 11 +- drivers/staging/qlge/qlge_mpi.c | 14 +- 3 files changed, 309 insertions(+), 299 deletions(-) -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/4] staging: qlge: fix trailing */ in block comment
Remove trailing "*/" in block comments. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 3 ++- drivers/staging/qlge/qlge_mpi.c | 10 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 1650de13842f..aaecf2b0f9a1 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx) */ ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id); /* Add the TX ring(s) serviced by this vector -* to the mask. */ +* to the mask. +*/ for (j = 0; j < tx_rings_per_vector; j++) { ctx->irq_mask |= (1 << qdev->rx_ring[qdev->rss_ring_count + diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 60c08d9cc034..3bb08d290525 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp) * This can get called iteratively from the mpi_work thread * when events arrive via an interrupt. * It also gets called when a mailbox command is polling for - * it's completion. */ + * it's completion. + */ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) { int status; @@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) * changed when a mailbox command is waiting * for a response and an AEN arrives and * is handled. -* */ +*/ mbcp->out_count = orig_count; return status; } @@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) * here because some AEN might arrive while * we're waiting for the mailbox command to * complete. If more than 5 seconds expire we can -* assume something is wrong. */ +* assume something is wrong. +*/ count = jiffies + HZ * MAILBOX_TIMEOUT; do { /* Wait for the interrupt to come in. */ @@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work) /* Signal the resulting link up AEN * that the frame routing and mac addr * needs to be set. -* */ +*/ set_bit(QL_CAM_RT_SET, >flags); /* Do ACK if required */ if (timeout) { -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 2/4] staging: qlge: fix else after return or break
Remove unnecessary elses after return or break. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 23 ++- drivers/staging/qlge/qlge_main.c | 8 drivers/staging/qlge/qlge_mpi.c | 4 ++-- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 058889687907..87433510a224 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); } + if (value[0]) + pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", + qdev->ndev->name, i, value[1], value[0], + value[2]); } for (i = 0; i < 32; i++) { if (ql_get_mac_addr_reg @@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); } + if (value[0]) + pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + qdev->ndev->name, i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } @@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of routing index register\n", __func__); return; - } else { - if (value) - pr_err("%s: Routing Mask %d = 0x%.08x\n", - qdev->ndev->name, i, value); } + if (value) + pr_err("%s: Routing Mask %d = 0x%.08x\n", + qdev->ndev->name, i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); } diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index aaecf2b0f9a1..0054c454506b 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev) "Failed to set magic packet on %s.\n", qdev->ndev->name); return status; - } else - netif_info(qdev, drv, qdev->ndev, - "Enabled magic packet successfully on %s.\n", - qdev->ndev->name); + } + netif_info(qdev, drv, qdev->ndev, + "Enabled magic packet successfully on %s.\n", + qdev->ndev->name); wol |= MB_WOL_MAGIC_PKT; } diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 3bb08d290525..fa178fc642a6 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) netif_err(qdev, ifup, qdev->ndev, "Failed to init CAM/Routing tables.\n"); return; - } else - clear_bit(QL_CAM_RT_SET, >flags); + } + clear_bit(QL_CAM_RT_SET, >flags); } /* Queue up a worker to check the frame -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 3/4] staging: qlge: fix ql_sem_unlock
Some functions return without releasing the lock. Replace return with break. Suggested-by Dan Carpenter . Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 87433510a224..63e965966ced 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1390,7 +1390,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { pr_err("%s: Failed read of mac index register\n", __func__); - return; + break; } if (value[0]) pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", @@ -1402,7 +1402,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) (qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) { pr_err("%s: Failed read of mac index register\n", __func__); - return; + break; } if (value[0]) pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", @@ -1424,7 +1424,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) if (ql_get_routing_reg(qdev, i, )) { pr_err("%s: Failed read of routing index register\n", __func__); - return; + break; } if (value) pr_err("%s: Routing Mask %d = 0x%.08x\n", -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: qlge: fix else after return or break
On Fri, Jun 26, 2020 at 05:06:33PM -0700, Joe Perches wrote: On Sat, 2020-06-27 at 07:57 +0800, Coiby Xu wrote: On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote: > On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote: > > Remove unnecessary elses after return or break. > > unrelated trivia: [] > looks like all of these could use netdev_err [] should we also replace all pr_errs with netdev_err in ql_dump_* functions? Ideally, anywhere a struct netdevice * is available, it should be used to output netdev_ in preference to pr_. Thank you for the explaining! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/4] fix trailing */ in block comment
Remove trailing "*/" in block comments. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 3 ++- drivers/staging/qlge/qlge_mpi.c | 10 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 1650de13842f..aaecf2b0f9a1 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx) */ ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id); /* Add the TX ring(s) serviced by this vector -* to the mask. */ +* to the mask. +*/ for (j = 0; j < tx_rings_per_vector; j++) { ctx->irq_mask |= (1 << qdev->rx_ring[qdev->rss_ring_count + diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 60c08d9cc034..3bb08d290525 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp) * This can get called iteratively from the mpi_work thread * when events arrive via an interrupt. * It also gets called when a mailbox command is polling for - * it's completion. */ + * it's completion. + */ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) { int status; @@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) * changed when a mailbox command is waiting * for a response and an AEN arrives and * is handled. -* */ +*/ mbcp->out_count = orig_count; return status; } @@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) * here because some AEN might arrive while * we're waiting for the mailbox command to * complete. If more than 5 seconds expire we can -* assume something is wrong. */ +* assume something is wrong. +*/ count = jiffies + HZ * MAILBOX_TIMEOUT; do { /* Wait for the interrupt to come in. */ @@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work) /* Signal the resulting link up AEN * that the frame routing and mac addr * needs to be set. -* */ +*/ set_bit(QL_CAM_RT_SET, >flags); /* Do ACK if required */ if (timeout) { -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/4] staging: qlge: coding style fix for the qlge driver
These patches fix three coding style problems for all files under drivers/staging/qlge, - trailing */ in block comment - unnecessary else after return or break - pr_err preferred over netdev_err and a bug about releasing lock. Coiby Xu (4): fix trailing */ in block comment fix else after return or break fix ql_sem_unlock replace pr_err with netdev_err drivers/staging/qlge/qlge_dbg.c | 583 --- drivers/staging/qlge/qlge_main.c | 11 +- drivers/staging/qlge/qlge_mpi.c | 14 +- 3 files changed, 309 insertions(+), 299 deletions(-) -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/4] replace pr_err with netdev_err
Replace all pr_errs with netdev_err. Suggested-by: Joe Perches Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 568 1 file changed, 289 insertions(+), 279 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 63e965966ced..32fbd30a6a2e 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -647,7 +647,7 @@ static void ql_get_mac_protocol_registers(struct ql_adapter *qdev, u32 *buf) max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT; break; default: - pr_err("Bad type!!! 0x%08x\n", type); + netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type); max_index = 0; max_offset = 0; break; @@ -1335,9 +1335,8 @@ static void ql_dump_intr_states(struct ql_adapter *qdev) for (i = 0; i < qdev->intr_count; i++) { ql_write32(qdev, INTR_EN, qdev->intr_context[i].intr_read_mask); value = ql_read32(qdev, INTR_EN); - pr_err("%s: Interrupt %d is %s\n", - qdev->ndev->name, i, - (value & INTR_EN_EN ? "enabled" : "disabled")); + netdev_err(qdev->ndev, "Interrupt %d is %s\n", i, + (value & INTR_EN_EN ? "enabled" : "disabled")); } } @@ -1345,13 +1344,14 @@ static void ql_dump_intr_states(struct ql_adapter *qdev) do { \ u32 data; \ ql_read_xgmac_reg(qdev, reg, );\ - pr_err("%s: %s = 0x%.08x\n", qdev->ndev->name, #reg, data); \ + netdev_err(qdev->ndev, "%s = 0x%.08x\n", #reg, data); \ } while (0) void ql_dump_xgmac_control_regs(struct ql_adapter *qdev) { if (ql_sem_spinlock(qdev, qdev->xg_sem_mask)) { - pr_err("%s: Couldn't get xgmac sem\n", __func__); + netdev_err(qdev->ndev, "%s: Couldn't get xgmac sem\n", + __func__); return; } DUMP_XGMAC(qdev, PAUSE_SRC_LO); @@ -1388,25 +1388,28 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) return; for (i = 0; i < 4; i++) { if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { - pr_err("%s: Failed read of mac index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of mac index register\n", + __func__); break; } if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); + netdev_err(qdev->ndev, + "CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", + i, value[1], value[0], value[2]); } for (i = 0; i < 32; i++) { if (ql_get_mac_addr_reg (qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) { - pr_err("%s: Failed read of mac index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of mac index register\n", + __func__); break; } if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); + netdev_err(qdev->ndev, + "MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } @@ -1422,23 +1425,25 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) for (i = 0; i < 16; i++) { value = 0; if (ql_get_routing_reg(qdev, i, )) { - pr_err("%s: Failed read of routing index register\n", - __func__); + netdev_err(qdev->ndev, + "%s: Failed read of routing index register\n", +
[PATCH 2/4] fix else after return or break
Remove unnecessary elses after return or break. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 23 ++- drivers/staging/qlge/qlge_main.c | 8 drivers/staging/qlge/qlge_mpi.c | 4 ++-- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 058889687907..87433510a224 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); } + if (value[0]) + pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", + qdev->ndev->name, i, value[1], value[0], + value[2]); } for (i = 0; i < 32; i++) { if (ql_get_mac_addr_reg @@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); } + if (value[0]) + pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + qdev->ndev->name, i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } @@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of routing index register\n", __func__); return; - } else { - if (value) - pr_err("%s: Routing Mask %d = 0x%.08x\n", - qdev->ndev->name, i, value); } + if (value) + pr_err("%s: Routing Mask %d = 0x%.08x\n", + qdev->ndev->name, i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); } diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index aaecf2b0f9a1..0054c454506b 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev) "Failed to set magic packet on %s.\n", qdev->ndev->name); return status; - } else - netif_info(qdev, drv, qdev->ndev, - "Enabled magic packet successfully on %s.\n", - qdev->ndev->name); + } + netif_info(qdev, drv, qdev->ndev, + "Enabled magic packet successfully on %s.\n", + qdev->ndev->name); wol |= MB_WOL_MAGIC_PKT; } diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 3bb08d290525..fa178fc642a6 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) netif_err(qdev, ifup, qdev->ndev, "Failed to init CAM/Routing tables.\n"); return; - } else - clear_bit(QL_CAM_RT_SET, >flags); + } + clear_bit(QL_CAM_RT_SET, >flags); } /* Queue up a worker to check the frame -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/4] fix ql_sem_unlock
Some functions return without releasing the lock. Replace return with break. Suggested-by Dan Carpenter . Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 87433510a224..63e965966ced 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1390,7 +1390,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) { pr_err("%s: Failed read of mac index register\n", __func__); - return; + break; } if (value[0]) pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", @@ -1402,7 +1402,7 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) (qdev, MAC_ADDR_TYPE_MULTI_MAC, i, value)) { pr_err("%s: Failed read of mac index register\n", __func__); - return; + break; } if (value[0]) pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", @@ -1424,7 +1424,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) if (ql_get_routing_reg(qdev, i, )) { pr_err("%s: Failed read of routing index register\n", __func__); - return; + break; } if (value) pr_err("%s: Routing Mask %d = 0x%.08x\n", -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: qlge: fix else after return or break
On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote: On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote: Remove unnecessary elses after return or break. unrelated trivia: diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c [] @@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); looks like all of these could use netdev_err netdev_err(qdev, "etc...", i, value[1], value[0], value[2]); etc... Should we also replace all pr_errs with netdev_err in ql_dump_* functions? I'm not sure how we will use ql_dump_*. For example, ql_dump_regs is not referred by any kernel source, so I guess it's for the sole purpose of debugging the driver by the developer. But one pr_err in ql_dump_routing_entries which is called by dl_dump_regs doesn't prints out the device name whereas the other does, void ql_dump_routing_entries(struct ql_adapter *qdev) { int i; u32 value; i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); if (i) return; for (i = 0; i < 16; i++) { value = 0; if (ql_get_routing_reg(qdev, i, )) { pr_err("%s: Failed read of routing index register\n", __func__); break; } if (value) pr_err("%s: Routing Mask %d = 0x%.08x\n", qdev->ndev->name, i, value); } -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: qlge: fix else after return or break
On Thu, Jun 25, 2020 at 03:13:14PM -0700, Joe Perches wrote: On Fri, 2020-06-26 at 05:57 +0800, Coiby Xu wrote: Remove unnecessary elses after return or break. unrelated trivia: diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c [] @@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); looks like all of these could use netdev_err netdev_err(qdev, "etc...", i, value[1], value[0], value[2]); etc... Interestingly, scripts/checkpatch.pl couldn't detect this problem. I once used printk(KERN_ALERT...) and the script would properly warn me that, WARNING: Prefer [subsystem eg: netdev]_alert([subsystem]dev, ... then dev_alert(dev, ... then pr_alert(... to printk(KERN_ALERT . I'll fix this issue when sending another version of the patches. Thank you for the reminding! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: qlge: fix else after return or break
On Fri, Jun 26, 2020 at 11:34:36AM +0300, Dan Carpenter wrote: On Fri, Jun 26, 2020 at 05:57:55AM +0800, Coiby Xu wrote: @@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; ^^ - } else { - if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); } + if (value[0]) + pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + qdev->ndev->name, i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); ^^^ } @@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of routing index register\n", __func__); return; ^^ - } else { - if (value) - pr_err("%s: Routing Mask %d = 0x%.08x\n", - qdev->ndev->name, i, value); } + if (value) + pr_err("%s: Routing Mask %d = 0x%.08x\n", + qdev->ndev->name, i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); } This is not caused by your patch, but in these two functions we return without dropping the lock. There may be other places as well, but these are the two I can see without leaving my email client. Do you think you could fix that before we forget? Just change the return to a break to fix the bug. Sure, I'll address this issue in the next series of patches. Thank you for bringing up this issue! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/2] fix trailing */ in block comment
On Thu, Jun 25, 2020 at 08:25:10PM +0300, Dan Carpenter wrote: The subject isn't right (no subsystem prefix) and we need a commit message. regards, dan carpenter Thank you for pointing out the exact problems! -- Best regards, Coiby ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] staging: qlge: fix trailing */ in block comment
Remove trailing "*/" in block comments. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 3 ++- drivers/staging/qlge/qlge_mpi.c | 10 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 1650de13842f..aaecf2b0f9a1 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx) */ ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id); /* Add the TX ring(s) serviced by this vector -* to the mask. */ +* to the mask. +*/ for (j = 0; j < tx_rings_per_vector; j++) { ctx->irq_mask |= (1 << qdev->rx_ring[qdev->rss_ring_count + diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 60c08d9cc034..3bb08d290525 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp) * This can get called iteratively from the mpi_work thread * when events arrive via an interrupt. * It also gets called when a mailbox command is polling for - * it's completion. */ + * it's completion. + */ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) { int status; @@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) * changed when a mailbox command is waiting * for a response and an AEN arrives and * is handled. -* */ +*/ mbcp->out_count = orig_count; return status; } @@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) * here because some AEN might arrive while * we're waiting for the mailbox command to * complete. If more than 5 seconds expire we can -* assume something is wrong. */ +* assume something is wrong. +*/ count = jiffies + HZ * MAILBOX_TIMEOUT; do { /* Wait for the interrupt to come in. */ @@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work) /* Signal the resulting link up AEN * that the frame routing and mac addr * needs to be set. -* */ +*/ set_bit(QL_CAM_RT_SET, >flags); /* Do ACK if required */ if (timeout) { -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] staging: qlge: fix else after return or break
Remove unnecessary elses after return or break. Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_dbg.c | 23 ++- drivers/staging/qlge/qlge_main.c | 8 drivers/staging/qlge/qlge_mpi.c | 4 ++-- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c index 058889687907..87433510a224 100644 --- a/drivers/staging/qlge/qlge_dbg.c +++ b/drivers/staging/qlge/qlge_dbg.c @@ -1391,12 +1391,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", - qdev->ndev->name, i, value[1], value[0], - value[2]); } + if (value[0]) + pr_err("%s: CAM index %d CAM Lookup Lower = 0x%.08x:%.08x, Output = 0x%.08x\n", + qdev->ndev->name, i, value[1], value[0], + value[2]); } for (i = 0; i < 32; i++) { if (ql_get_mac_addr_reg @@ -1404,11 +1403,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of mac index register\n", __func__); return; - } else { - if (value[0]) - pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", - qdev->ndev->name, i, value[1], value[0]); } + if (value[0]) + pr_err("%s: MCAST index %d CAM Lookup Lower = 0x%.08x:%.08x\n", + qdev->ndev->name, i, value[1], value[0]); } ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); } @@ -1427,11 +1425,10 @@ void ql_dump_routing_entries(struct ql_adapter *qdev) pr_err("%s: Failed read of routing index register\n", __func__); return; - } else { - if (value) - pr_err("%s: Routing Mask %d = 0x%.08x\n", - qdev->ndev->name, i, value); } + if (value) + pr_err("%s: Routing Mask %d = 0x%.08x\n", + qdev->ndev->name, i, value); } ql_sem_unlock(qdev, SEM_RT_IDX_MASK); } diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index aaecf2b0f9a1..0054c454506b 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3778,10 +3778,10 @@ static int ql_wol(struct ql_adapter *qdev) "Failed to set magic packet on %s.\n", qdev->ndev->name); return status; - } else - netif_info(qdev, drv, qdev->ndev, - "Enabled magic packet successfully on %s.\n", - qdev->ndev->name); + } + netif_info(qdev, drv, qdev->ndev, + "Enabled magic packet successfully on %s.\n", + qdev->ndev->name); wol |= MB_WOL_MAGIC_PKT; } diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 3bb08d290525..fa178fc642a6 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -276,8 +276,8 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) netif_err(qdev, ifup, qdev->ndev, "Failed to init CAM/Routing tables.\n"); return; - } else - clear_bit(QL_CAM_RT_SET, >flags); + } + clear_bit(QL_CAM_RT_SET, >flags); } /* Queue up a worker to check the frame -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/2] staging: qlge: coding style fix for the qlge driver
These two patches fix two coding style problems for all files under drivers/staging/qlge as reported by checkpatch.pl, - trailing */ in block comment - unnecessary else after return or break Coiby Xu (2): fix trailing */ in block comment fix else after return or break drivers/staging/qlge/qlge_dbg.c | 23 ++- drivers/staging/qlge/qlge_main.c | 11 ++- drivers/staging/qlge/qlge_mpi.c | 14 -- 3 files changed, 24 insertions(+), 24 deletions(-) -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] fix trailing */ in block comment
Signed-off-by: Coiby Xu --- drivers/staging/qlge/qlge_main.c | 3 ++- drivers/staging/qlge/qlge_mpi.c | 10 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c index 1650de13842f..aaecf2b0f9a1 100644 --- a/drivers/staging/qlge/qlge_main.c +++ b/drivers/staging/qlge/qlge_main.c @@ -3244,7 +3244,8 @@ static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx) */ ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id); /* Add the TX ring(s) serviced by this vector -* to the mask. */ +* to the mask. +*/ for (j = 0; j < tx_rings_per_vector; j++) { ctx->irq_mask |= (1 << qdev->rx_ring[qdev->rss_ring_count + diff --git a/drivers/staging/qlge/qlge_mpi.c b/drivers/staging/qlge/qlge_mpi.c index 60c08d9cc034..3bb08d290525 100644 --- a/drivers/staging/qlge/qlge_mpi.c +++ b/drivers/staging/qlge/qlge_mpi.c @@ -389,7 +389,8 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp) * This can get called iteratively from the mpi_work thread * when events arrive via an interrupt. * It also gets called when a mailbox command is polling for - * it's completion. */ + * it's completion. + */ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) { int status; @@ -520,7 +521,7 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) * changed when a mailbox command is waiting * for a response and an AEN arrives and * is handled. -* */ +*/ mbcp->out_count = orig_count; return status; } @@ -555,7 +556,8 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) * here because some AEN might arrive while * we're waiting for the mailbox command to * complete. If more than 5 seconds expire we can -* assume something is wrong. */ +* assume something is wrong. +*/ count = jiffies + HZ * MAILBOX_TIMEOUT; do { /* Wait for the interrupt to come in. */ @@ -1178,7 +1180,7 @@ void ql_mpi_idc_work(struct work_struct *work) /* Signal the resulting link up AEN * that the frame routing and mac addr * needs to be set. -* */ +*/ set_bit(QL_CAM_RT_SET, >flags); /* Do ACK if required */ if (timeout) { -- 2.27.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel