On Mon, Feb 29, 2016 at 02:58:16AM -0500, Valdis.Kletnieks@vt.edu wrote:
On Mon, 29 Feb 2016 14:41:34 +0800, Navy Cheng said:
pci_unregister_driver() should be used once dgnc module exit. It has nothing to do with dgnc_NumBoards. Remove the judgment of dgnc_NumBoards to avoid pci_unregister_driver() is not used when dgnc_NumBoards is 0.
- if (dgnc_NumBoards) - pci_unregister_driver(&dgnc_driver); + pci_unregister_driver(&dgnc_driver);
Does pci_unregister_driver do the right thing if there are 0 boards in the system?
I have no dgnc device in my laptop. After *insmod* and *rmmod* dgnc module, I can re-insmod dgnc successfully. If dgnc is *rmmod*, the dgnc-file in /sys will disappear.
If this logic is wrong, shouldn't there also be a patch fixing the following in dgnc_init_module()?
Yes, I thought dgnc_init_module should be fixed. But I'm not familiar with how to submitting patchset. I decide to fix dgnc_cleanup_module() first.
/* * Find and configure all the cards */ rc = pci_register_driver(&dgnc_driver);
/* * If something went wrong in the scan, bail out of driver. */ if (rc < 0) { /* Only unregister if it was actually registered. */ if (dgnc_NumBoards) pci_unregister_driver(&dgnc_driver); else pr_warn("WARNING: dgnc driver load failed. No Digi Neo or Classic boards found.\n");
dgnc_cleanup_module();
While I'm at it, the entire NumBoards counting seems to be wonky - it looks like a *lot* of off-by-one errors. Looks like the programmer(s) weren't sure if they wanted to use that as a zero-based or one-based counter/index.
Maybe we can fix the *init* and *exit* like this: static int __init dgnc_init_module(void) { int rc; rc = dgnc_start(); if (rc < 0) goto err1; rc = pci_register_driver(&dgnc_driver) if (rc <0) { goto err1; pr_warn("...."); } rc = dgnc_create_driver_sysfiles(&dgnc_driver); if (rc = 0) goto err2; return rc; err2: pci_unregister_driver(&dgnc_driver); err1: dgnc_end(); return rc; } static void dgnc_cleanup_module(void) { int i; dgnc_remove_driver_sysfiles(&dgnc_driver); for (i = 0; i < dgnc_NumBoards; ++i) { dgnc_remove_ports_sysfiles(dgnc_Board[i]); dgnc_tty_uninit(dgnc_Board[i]); dgnc_cleanup_board(dgnc_Board[i]); } pci_unregister_driver(&dgnc_driver); dgnc_end(); }