From: "Bryan O'Sullivan" <bos@pathscale.com>
To: rdreier@cisco.com
Cc: linux-kernel@vger.kernel.org, openib-general@openib.org
Subject: [PATCH 20 of 28] IB/ipath - clean up module exit code
Date: Thu, 28 Sep 2006 09:00:16 -0700 [thread overview]
Message-ID: <e3158e62d6bf923cadc2.1159459216@eng-12.pathscale.com> (raw)
In-Reply-To: <patchbomb.1159459196@eng-12.pathscale.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
diff -r 858280e8cbab -r e3158e62d6bf drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c Thu Sep 28 08:57:12 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c Thu Sep 28 08:57:13 2006 -0700
@@ -517,33 +517,146 @@ bail:
return ret;
}
+static void __devexit cleanup_device(struct ipath_devdata *dd)
+{
+ int port;
+
+ ipath_shutdown_device(dd);
+
+ if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
+ /* can't do anything more with chip; needs re-init */
+ *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
+ if (dd->ipath_kregbase) {
+ /*
+ * if we haven't already cleaned up before these are
+ * to ensure any register reads/writes "fail" until
+ * re-init
+ */
+ dd->ipath_kregbase = NULL;
+ dd->ipath_uregbase = 0;
+ dd->ipath_sregbase = 0;
+ dd->ipath_cregbase = 0;
+ dd->ipath_kregsize = 0;
+ }
+ ipath_disable_wc(dd);
+ }
+
+ if (dd->ipath_pioavailregs_dma) {
+ dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
+ (void *) dd->ipath_pioavailregs_dma,
+ dd->ipath_pioavailregs_phys);
+ dd->ipath_pioavailregs_dma = NULL;
+ }
+ if (dd->ipath_dummy_hdrq) {
+ dma_free_coherent(&dd->pcidev->dev,
+ dd->ipath_pd[0]->port_rcvhdrq_size,
+ dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
+ dd->ipath_dummy_hdrq = NULL;
+ }
+
+ if (dd->ipath_pageshadow) {
+ struct page **tmpp = dd->ipath_pageshadow;
+ dma_addr_t *tmpd = dd->ipath_physshadow;
+ int i, cnt = 0;
+
+ ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
+ "locked\n");
+ for (port = 0; port < dd->ipath_cfgports; port++) {
+ int port_tidbase = port * dd->ipath_rcvtidcnt;
+ int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
+ for (i = port_tidbase; i < maxtid; i++) {
+ if (!tmpp[i])
+ continue;
+ pci_unmap_page(dd->pcidev, tmpd[i],
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ ipath_release_user_pages(&tmpp[i], 1);
+ tmpp[i] = NULL;
+ cnt++;
+ }
+ }
+ if (cnt) {
+ ipath_stats.sps_pageunlocks += cnt;
+ ipath_cdbg(VERBOSE, "There were still %u expTID "
+ "entries locked\n", cnt);
+ }
+ if (ipath_stats.sps_pagelocks ||
+ ipath_stats.sps_pageunlocks)
+ ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
+ "unlocked via ipath_m{un}lock\n",
+ (unsigned long long)
+ ipath_stats.sps_pagelocks,
+ (unsigned long long)
+ ipath_stats.sps_pageunlocks);
+
+ ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
+ dd->ipath_pageshadow);
+ vfree(dd->ipath_pageshadow);
+ dd->ipath_pageshadow = NULL;
+ }
+
+ /*
+ * free any resources still in use (usually just kernel ports)
+ * at unload; we do for portcnt, not cfgports, because cfgports
+ * could have changed while we were loaded.
+ */
+ for (port = 0; port < dd->ipath_portcnt; port++) {
+ struct ipath_portdata *pd = dd->ipath_pd[port];
+ dd->ipath_pd[port] = NULL;
+ ipath_free_pddata(dd, pd);
+ }
+ kfree(dd->ipath_pd);
+ /*
+ * debuggability, in case some cleanup path tries to use it
+ * after this
+ */
+ dd->ipath_pd = NULL;
+}
+
static void __devexit ipath_remove_one(struct pci_dev *pdev)
{
- struct ipath_devdata *dd;
-
- ipath_cdbg(VERBOSE, "removing, pdev=%p\n", pdev);
- if (!pdev)
- return;
-
- dd = pci_get_drvdata(pdev);
-
- if (dd->verbs_dev) {
+ struct ipath_devdata *dd = pci_get_drvdata(pdev);
+
+ ipath_cdbg(VERBOSE, "removing, pdev=%p, dd=%p\n", pdev, dd);
+
+ if (dd->verbs_dev)
ipath_unregister_ib_device(dd->verbs_dev);
- dd->verbs_dev = NULL;
- }
ipath_diag_remove(dd);
ipath_user_remove(dd);
ipathfs_remove_device(dd);
ipath_device_remove_group(&pdev->dev, dd);
+
ipath_cdbg(VERBOSE, "Releasing pci memory regions, dd %p, "
"unit %u\n", dd, (u32) dd->ipath_unit);
- if (dd->ipath_kregbase) {
- ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n",
- dd->ipath_kregbase);
- iounmap((volatile void __iomem *) dd->ipath_kregbase);
- dd->ipath_kregbase = NULL;
- }
+
+ cleanup_device(dd);
+
+ /*
+ * turn off rcv, send, and interrupts for all ports, all drivers
+ * should also hard reset the chip here?
+ * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
+ * for all versions of the driver, if they were allocated
+ */
+ if (pdev->irq) {
+ ipath_cdbg(VERBOSE,
+ "unit %u free_irq of irq %x\n",
+ dd->ipath_unit, pdev->irq);
+ free_irq(pdev->irq, dd);
+ } else
+ ipath_dbg("irq is 0, not doing free_irq "
+ "for unit %u\n", dd->ipath_unit);
+ /*
+ * we check for NULL here, because it's outside
+ * the kregbase check, and we need to call it
+ * after the free_irq. Thus it's possible that
+ * the function pointers were never initialized.
+ */
+ if (dd->ipath_f_cleanup)
+ /* clean up chip-specific stuff */
+ dd->ipath_f_cleanup(dd);
+
+ ipath_cdbg(VERBOSE, "Unmapping kregbase %p\n", dd->ipath_kregbase);
+ iounmap((volatile void __iomem *) dd->ipath_kregbase);
pci_release_regions(pdev);
ipath_cdbg(VERBOSE, "calling pci_disable_device\n");
pci_disable_device(pdev);
@@ -1917,157 +2030,11 @@ bail:
return ret;
}
-static void cleanup_device(struct ipath_devdata *dd)
-{
- int port;
-
- ipath_shutdown_device(dd);
-
- if (*dd->ipath_statusp & IPATH_STATUS_CHIP_PRESENT) {
- /* can't do anything more with chip; needs re-init */
- *dd->ipath_statusp &= ~IPATH_STATUS_CHIP_PRESENT;
- if (dd->ipath_kregbase) {
- /*
- * if we haven't already cleaned up before these are
- * to ensure any register reads/writes "fail" until
- * re-init
- */
- dd->ipath_kregbase = NULL;
- dd->ipath_uregbase = 0;
- dd->ipath_sregbase = 0;
- dd->ipath_cregbase = 0;
- dd->ipath_kregsize = 0;
- }
- ipath_disable_wc(dd);
- }
-
- if (dd->ipath_pioavailregs_dma) {
- dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE,
- (void *) dd->ipath_pioavailregs_dma,
- dd->ipath_pioavailregs_phys);
- dd->ipath_pioavailregs_dma = NULL;
- }
- if (dd->ipath_dummy_hdrq) {
- dma_free_coherent(&dd->pcidev->dev,
- dd->ipath_pd[0]->port_rcvhdrq_size,
- dd->ipath_dummy_hdrq, dd->ipath_dummy_hdrq_phys);
- dd->ipath_dummy_hdrq = NULL;
- }
-
- if (dd->ipath_pageshadow) {
- struct page **tmpp = dd->ipath_pageshadow;
- dma_addr_t *tmpd = dd->ipath_physshadow;
- int i, cnt = 0;
-
- ipath_cdbg(VERBOSE, "Unlocking any expTID pages still "
- "locked\n");
- for (port = 0; port < dd->ipath_cfgports; port++) {
- int port_tidbase = port * dd->ipath_rcvtidcnt;
- int maxtid = port_tidbase + dd->ipath_rcvtidcnt;
- for (i = port_tidbase; i < maxtid; i++) {
- if (!tmpp[i])
- continue;
- pci_unmap_page(dd->pcidev, tmpd[i],
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
- ipath_release_user_pages(&tmpp[i], 1);
- tmpp[i] = NULL;
- cnt++;
- }
- }
- if (cnt) {
- ipath_stats.sps_pageunlocks += cnt;
- ipath_cdbg(VERBOSE, "There were still %u expTID "
- "entries locked\n", cnt);
- }
- if (ipath_stats.sps_pagelocks ||
- ipath_stats.sps_pageunlocks)
- ipath_cdbg(VERBOSE, "%llu pages locked, %llu "
- "unlocked via ipath_m{un}lock\n",
- (unsigned long long)
- ipath_stats.sps_pagelocks,
- (unsigned long long)
- ipath_stats.sps_pageunlocks);
-
- ipath_cdbg(VERBOSE, "Free shadow page tid array at %p\n",
- dd->ipath_pageshadow);
- vfree(dd->ipath_pageshadow);
- dd->ipath_pageshadow = NULL;
- }
-
- /*
- * free any resources still in use (usually just kernel ports)
- * at unload; we do for portcnt, not cfgports, because cfgports
- * could have changed while we were loaded.
- */
- for (port = 0; port < dd->ipath_portcnt; port++) {
- struct ipath_portdata *pd = dd->ipath_pd[port];
- dd->ipath_pd[port] = NULL;
- ipath_free_pddata(dd, pd);
- }
- kfree(dd->ipath_pd);
- /*
- * debuggability, in case some cleanup path tries to use it
- * after this
- */
- dd->ipath_pd = NULL;
-}
-
static void __exit infinipath_cleanup(void)
{
- struct ipath_devdata *dd, *tmp;
- unsigned long flags;
-
- ipath_diagpkt_remove();
-
ipath_exit_ipathfs();
ipath_driver_remove_group(&ipath_driver.driver);
-
- spin_lock_irqsave(&ipath_devs_lock, flags);
-
- /*
- * turn off rcv, send, and interrupts for all ports, all drivers
- * should also hard reset the chip here?
- * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs
- * for all versions of the driver, if they were allocated
- */
- list_for_each_entry_safe(dd, tmp, &ipath_dev_list, ipath_list) {
- spin_unlock_irqrestore(&ipath_devs_lock, flags);
-
- if (dd->verbs_dev) {
- ipath_unregister_ib_device(dd->verbs_dev);
- dd->verbs_dev = NULL;
- }
-
- if (dd->ipath_kregbase)
- cleanup_device(dd);
-
- if (dd->pcidev) {
- if (dd->pcidev->irq) {
- ipath_cdbg(VERBOSE,
- "unit %u free_irq of irq %x\n",
- dd->ipath_unit, dd->pcidev->irq);
- free_irq(dd->pcidev->irq, dd);
- } else
- ipath_dbg("irq is 0, not doing free_irq "
- "for unit %u\n", dd->ipath_unit);
-
- /*
- * we check for NULL here, because it's outside
- * the kregbase check, and we need to call it
- * after the free_irq. Thus it's possible that
- * the function pointers were never initialized.
- */
- if (dd->ipath_f_cleanup)
- /* clean up chip-specific stuff */
- dd->ipath_f_cleanup(dd);
-
- dd->pcidev = NULL;
- }
- spin_lock_irqsave(&ipath_devs_lock, flags);
- }
-
- spin_unlock_irqrestore(&ipath_devs_lock, flags);
ipath_cdbg(VERBOSE, "Unregistering pci driver\n");
pci_unregister_driver(&ipath_driver);
next prev parent reply other threads:[~2006-09-28 16:02 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-28 15:59 [PATCH 0 of 28] ipath patches for 2.6.19 Bryan O'Sullivan
2006-09-28 15:59 ` [PATCH 1 of 28] IB/ipath - limit # of packets sent without an ACK received Bryan O'Sullivan
2006-09-28 18:16 ` Roland Dreier
2006-09-28 18:33 ` Bryan O'Sullivan
2006-09-28 15:59 ` [PATCH 2 of 28] IB/ipath - fix memory leak if allocation fails Bryan O'Sullivan
2006-09-28 15:59 ` [PATCH 3 of 28] IB/ipath - driver support for userspace sharing of HW contexts Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 4 of 28] IB/ipath - support revision 2 InfiniPath PCIE devices Bryan O'Sullivan
2006-09-28 18:15 ` Roland Dreier
2006-09-28 16:00 ` [PATCH 5 of 28] IB/ipath - unregister from IB core early Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 6 of 28] IB/ipath - clean up handling of GUID 0 Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 7 of 28] IB/ipath - lock and count allocated CQs properly Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 8 of 28] IB/ipath - count SRQs properly Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 9 of 28] IB/ipath - only allow complete writes to flash Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 10 of 28] IB/ipath - RC and UC should validate SLID and DLID Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 11 of 28] IB/ipath - ensure that PD of MR matches PD of QP checking the Rkey Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 12 of 28] IB/ipath - print more informative parity error messages Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 13 of 28] IB/ipath - fix compiler warnings and errors on non-x86_64 systems Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 14 of 28] IB/ipath - Fix mismatch in shifts and masks for printing debug info Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 15 of 28] IB/ipath - support multiple simultaneous devices of different types Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 16 of 28] IB/ipath - drop unnecessary "(void *)" casts Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 17 of 28] IB/ipath - improved support for powerpc Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 18 of 28] IB/ipath - flush RWQEs if access error or invalid error seen Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 19 of 28] IB/ipath - call mtrr_del with correct arguments Bryan O'Sullivan
2006-09-28 16:00 ` Bryan O'Sullivan [this message]
2006-09-28 16:00 ` [PATCH 21 of 28] IB/ipath - change HT CRC message to indicate how to resolve problem Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 22 of 28] IB/ipath - fix and recover TXE piobuf and PBC parity errors Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 23 of 28] IB/ipath - fix EEPROM read when driver is compiled with -Os Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 24 of 28] IB/mthca - Fix compiler warnings with gcc4 on possible unitialized variables Bryan O'Sullivan
2006-09-28 18:14 ` Roland Dreier
2006-09-28 20:46 ` Jeremy Fitzhardinge
2006-09-28 16:00 ` [PATCH 25 of 28] IB/ipath - Set CPU affinity early Bryan O'Sullivan
2006-09-28 18:15 ` Roland Dreier
2006-09-28 16:00 ` [PATCH 26 of 28] IB/ipath - support new PCIE device, QLE7142 Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 27 of 28] IB/ipath - fix races with ib_resize_cq() Bryan O'Sullivan
2006-09-28 16:00 ` [PATCH 28 of 28] IB/ipath - fix lockdep error upon "ifconfig ibN down" Bryan O'Sullivan
2006-09-30 0:36 ` [PATCH 0 of 28] ipath patches for 2.6.19 Eric W. Biederman
2006-10-02 18:14 ` Bryan O'Sullivan
2006-10-03 1:22 ` Eric W. Biederman
2006-10-03 15:25 ` Bryan O'Sullivan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e3158e62d6bf923cadc2.1159459216@eng-12.pathscale.com \
--to=bos@pathscale.com \
--cc=linux-kernel@vger.kernel.org \
--cc=openib-general@openib.org \
--cc=rdreier@cisco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®