summary refs log tree commit diff
path: root/drivers/net/arcnet/com20020-pci.c
diff options
context:
space:
mode:
authorAhmed S. Darwish <a.darwish@linutronix.de>2021-01-28 20:48:02 +0100
committerJakub Kicinski <kuba@kernel.org>2021-01-29 20:54:06 -0800
commit01365633bd1c836240f9bbf86bbeee749795480a (patch)
tree3577317374618d0bc6a75a91ff346ba916e3868e /drivers/net/arcnet/com20020-pci.c
parent06cc6e5dc659e1995804cbeda643d0fa45b68999 (diff)
downloadlinux-01365633bd1c836240f9bbf86bbeee749795480a.tar.gz
net: arcnet: Fix RESET flag handling
The main arcnet interrupt handler calls arcnet_close() then
arcnet_open(), if the RESET status flag is encountered.

This is invalid:

  1) In general, interrupt handlers should never call ->ndo_stop() and
     ->ndo_open() functions. They are usually full of blocking calls and
     other methods that are expected to be called only from drivers
     init and exit code paths.

  2) arcnet_close() contains a del_timer_sync(). If the irq handler
     interrupts the to-be-deleted timer, del_timer_sync() will just loop
     forever.

  3) arcnet_close() also calls tasklet_kill(), which has a warning if
     called from irq context.

  4) For device reset, the sequence "arcnet_close(); arcnet_open();" is
     not complete.  Some children arcnet drivers have special init/exit
     code sequences, which then embed a call to arcnet_open() and
     arcnet_close() accordingly. Check drivers/net/arcnet/com20020.c.

Run the device RESET sequence from a scheduled workqueue instead.

Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/20210128194802.727770-1-a.darwish@linutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/arcnet/com20020-pci.c')
-rw-r--r--drivers/net/arcnet/com20020-pci.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index eb7f76753c9c..8bdc44b7e09a 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -291,7 +291,7 @@ static void com20020pci_remove(struct pci_dev *pdev)
 
 		unregister_netdev(dev);
 		free_irq(dev->irq, dev);
-		free_netdev(dev);
+		free_arcdev(dev);
 	}
 }