* [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure
@ 2026-09-15 17:31 Guangshuo Li
2026-09-16 17:30 ` kernel test robot
2026-09-16 19:07 ` kernel test robot
0 siblings, 2 replies; 3+ messages in thread
From: Guangshuo Li @ 2026-09-15 17:31 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Stéphane Grosjean,
Kees Cook, Guangshuo Li, Wolfgang Grandegger, linux-can,
linux-kernel
Cc: stable
peak_pci_probe() initializes the PCIeC resources before registering the
SJA1000 network device.
On the probe error path, the registered channels are freed with
free_sja1000dev() before peak_pciec_remove() is called. Since chan is
part of the netdev private data, accessing chan->pciec_card after
free_sja1000dev() results in a use-after-free.
There is also a similar cleanup issue when peak_pciec_probe() succeeds
for the first channel but register_sja1000dev() subsequently fails. In
that case, the netdev is freed without releasing the PCIeC resources.
Clean up the PCIeC resources before freeing the first channel, matching
the ordering used by peak_pci_remove(), and also release them when
registration of the first channel fails.
This issue was found by manual code inspection.
Fixes: e6d9c80b7ca1 ("can: peak_pci: add support of some new PEAK-System PCI cards")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/net/can/sja1000/peak_pci.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
index 69c61ccf621d..28b94e642170 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -697,6 +697,8 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
failure_free_dev:
+if (!chan->prev_dev && chan->pciec_card)
+ peak_pciec_remove(chan->pciec_card);
pci_set_drvdata(pdev, chan->prev_dev);
free_sja1000dev(dev);
@@ -704,20 +706,18 @@ static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Disable interrupts */
writew(0x0, cfg_base + PITA_ICR + 2);
- chan = NULL;
for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
priv = netdev_priv(dev);
chan = priv->priv;
prev_dev = chan->prev_dev;
+ /* do that only for first channel */
+ if (!prev_dev && chan->pciec_card)
+ peak_pciec_remove(chan->pciec_card);
unregister_sja1000dev(dev);
free_sja1000dev(dev);
}
- /* free any PCIeC resources too */
- if (chan && chan->pciec_card)
- peak_pciec_remove(chan->pciec_card);
-
pci_iounmap(pdev, reg_base);
failure_unmap_cfg_base:
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure
2026-09-15 17:31 [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure Guangshuo Li
@ 2026-09-16 17:30 ` kernel test robot
2026-09-16 19:07 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-09-16 17:30 UTC (permalink / raw)
To: Guangshuo Li, Marc Kleine-Budde, Vincent Mailhol,
Stéphane Grosjean, Kees Cook, Wolfgang Grandegger,
linux-can, linux-kernel
Cc: oe-kbuild-all, stable
Hi Guangshuo,
kernel test robot noticed the following build warnings:
[auto build test WARNING on mkl-can-next/testing]
[also build test WARNING on linus/master v7.3-rc3 next-20260914]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Guangshuo-Li/can-peak_pci-fix-PCIeC-cleanup-on-probe-failure/20260916-013157
base: https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git testing
patch link: https://lore.kernel.org/r/20260915173157.2510375-1-lgs201920130244%40gmail.com
patch subject: [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure
config: sparc64-randconfig-1000-20260916 (https://download.01.org/0day-ci/archive/20260917/202609170102.yZBQuFMY-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260917/202609170102.yZBQuFMY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609170102.yZBQuFMY-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/net/can/sja1000/peak_pci.c: In function 'peak_pci_probe':
>> drivers/net/can/sja1000/peak_pci.c:700:1: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if (!chan->prev_dev && chan->pciec_card)
^~
drivers/net/can/sja1000/peak_pci.c:702:2: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
pci_set_drvdata(pdev, chan->prev_dev);
^~~~~~~~~~~~~~~
vim +/if +700 drivers/net/can/sja1000/peak_pci.c
550
551 static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
552 {
553 struct sja1000_priv *priv;
554 struct peak_pci_chan *chan;
555 struct net_device *dev, *prev_dev;
556 void __iomem *cfg_base, *reg_base;
557 u16 sub_sys_id, icr;
558 int i, err, channels;
559 char fw_str[14] = "";
560
561 err = pci_enable_device(pdev);
562 if (err)
563 return err;
564
565 err = pci_request_regions(pdev, DRV_NAME);
566 if (err)
567 goto failure_disable_pci;
568
569 err = pci_read_config_word(pdev, 0x2e, &sub_sys_id);
570 if (err)
571 goto failure_release_regions;
572
573 dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n",
574 pdev->vendor, pdev->device, sub_sys_id);
575
576 err = pci_write_config_word(pdev, 0x44, 0);
577 if (err)
578 goto failure_release_regions;
579
580 if (sub_sys_id >= 12)
581 channels = 4;
582 else if (sub_sys_id >= 10)
583 channels = 3;
584 else if (sub_sys_id >= 4)
585 channels = 2;
586 else
587 channels = 1;
588
589 cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE);
590 if (!cfg_base) {
591 dev_err(&pdev->dev, "failed to map PCI resource #0\n");
592 err = -ENOMEM;
593 goto failure_release_regions;
594 }
595
596 reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels);
597 if (!reg_base) {
598 dev_err(&pdev->dev, "failed to map PCI resource #1\n");
599 err = -ENOMEM;
600 goto failure_unmap_cfg_base;
601 }
602
603 /* Set GPIO control register */
604 writew(0x0005, cfg_base + PITA_GPIOICR + 2);
605 /* Enable all channels of this card */
606 writeb(0x00, cfg_base + PITA_GPIOICR);
607 /* Toggle reset */
608 writeb(0x05, cfg_base + PITA_MISC + 3);
609 usleep_range(5000, 6000);
610 /* Leave parport mux mode */
611 writeb(0x04, cfg_base + PITA_MISC + 3);
612
613 /* FPGA equipped card if not 0 */
614 if (readl(cfg_base + PEAK_VER_REG1)) {
615 /* FPGA card: display version of the running firmware */
616 u32 fw_ver = readl(cfg_base + PEAK_VER_REG2);
617
618 snprintf(fw_str, sizeof(fw_str), " FW v%u.%u.%u",
619 (fw_ver >> 12) & 0xf,
620 (fw_ver >> 8) & 0xf,
621 (fw_ver >> 4) & 0xf);
622 }
623
624 /* Display commercial name (and, eventually, FW version) of the card */
625 dev_info(&pdev->dev, "%ux CAN %s%s\n",
626 channels, (const char *)ent->driver_data, fw_str);
627
628 icr = readw(cfg_base + PITA_ICR + 2);
629
630 for (i = 0; i < channels; i++) {
631 dev = alloc_sja1000dev(sizeof(struct peak_pci_chan));
632 if (!dev) {
633 err = -ENOMEM;
634 goto failure_remove_channels;
635 }
636
637 priv = netdev_priv(dev);
638 chan = priv->priv;
639
640 chan->cfg_base = cfg_base;
641 priv->reg_base = reg_base + i * PEAK_PCI_CHAN_SIZE;
642
643 priv->read_reg = peak_pci_read_reg;
644 priv->write_reg = peak_pci_write_reg;
645 priv->post_irq = peak_pci_post_irq;
646
647 priv->can.clock.freq = PEAK_PCI_CAN_CLOCK;
648 priv->ocr = PEAK_PCI_OCR;
649 priv->cdr = PEAK_PCI_CDR;
650 /* Neither a slave nor a single device distributes the clock */
651 if (channels == 1 || i > 0)
652 priv->cdr |= CDR_CLK_OFF;
653
654 /* Setup interrupt handling */
655 priv->irq_flags = IRQF_SHARED;
656 dev->irq = pdev->irq;
657
658 chan->icr_mask = peak_pci_icr_masks[i];
659 icr |= chan->icr_mask;
660
661 SET_NETDEV_DEV(dev, &pdev->dev);
662 dev->dev_id = i;
663
664 /* Create chain of SJA1000 devices */
665 chan->prev_dev = pci_get_drvdata(pdev);
666 pci_set_drvdata(pdev, dev);
667
668 /* PCAN-ExpressCard needs some additional i2c init.
669 * This must be done *before* register_sja1000dev() but
670 * *after* devices linkage
671 */
672 if (pdev->device == PEAK_PCIEC_DEVICE_ID ||
673 pdev->device == PEAK_PCIEC34_DEVICE_ID) {
674 err = peak_pciec_probe(pdev, dev);
675 if (err) {
676 dev_err(&pdev->dev,
677 "failed to probe device (err %d)\n",
678 err);
679 goto failure_free_dev;
680 }
681 }
682
683 err = register_sja1000dev(dev);
684 if (err) {
685 dev_err(&pdev->dev, "failed to register device\n");
686 goto failure_free_dev;
687 }
688
689 dev_info(&pdev->dev,
690 "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
691 dev->name, priv->reg_base, chan->cfg_base, dev->irq);
692 }
693
694 /* Enable interrupts */
695 writew(icr, cfg_base + PITA_ICR + 2);
696
697 return 0;
698
699 failure_free_dev:
> 700 if (!chan->prev_dev && chan->pciec_card)
701 peak_pciec_remove(chan->pciec_card);
702 pci_set_drvdata(pdev, chan->prev_dev);
703 free_sja1000dev(dev);
704
705 failure_remove_channels:
706 /* Disable interrupts */
707 writew(0x0, cfg_base + PITA_ICR + 2);
708
709 for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
710 priv = netdev_priv(dev);
711 chan = priv->priv;
712 prev_dev = chan->prev_dev;
713
714 /* do that only for first channel */
715 if (!prev_dev && chan->pciec_card)
716 peak_pciec_remove(chan->pciec_card);
717 unregister_sja1000dev(dev);
718 free_sja1000dev(dev);
719 }
720
721 pci_iounmap(pdev, reg_base);
722
723 failure_unmap_cfg_base:
724 pci_iounmap(pdev, cfg_base);
725
726 failure_release_regions:
727 pci_release_regions(pdev);
728
729 failure_disable_pci:
730 pci_disable_device(pdev);
731
732 /* pci_xxx_config_word() return positive PCIBIOS_xxx error codes while
733 * the probe() function must return a negative errno in case of failure
734 * (err is unchanged if negative)
735 */
736 return pcibios_err_to_errno(err);
737 }
738
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure
2026-09-15 17:31 [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure Guangshuo Li
2026-09-16 17:30 ` kernel test robot
@ 2026-09-16 19:07 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-09-16 19:07 UTC (permalink / raw)
To: Guangshuo Li, Marc Kleine-Budde, Vincent Mailhol,
Stéphane Grosjean, Kees Cook, Wolfgang Grandegger,
linux-can, linux-kernel
Cc: llvm, oe-kbuild-all, stable
Hi Guangshuo,
kernel test robot noticed the following build warnings:
[auto build test WARNING on mkl-can-next/testing]
[also build test WARNING on linus/master v7.3-rc3 next-20260914]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Guangshuo-Li/can-peak_pci-fix-PCIeC-cleanup-on-probe-failure/20260916-013157
base: https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git testing
patch link: https://lore.kernel.org/r/20260915173157.2510375-1-lgs201920130244%40gmail.com
patch subject: [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20260917/202609170334.HGvXQS1L-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260917/202609170334.HGvXQS1L-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609170334.HGvXQS1L-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/can/sja1000/peak_pci.c:702:2: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]
702 | pci_set_drvdata(pdev, chan->prev_dev);
| ^
drivers/net/can/sja1000/peak_pci.c:700:1: note: previous statement is here
700 | if (!chan->prev_dev && chan->pciec_card)
| ^
1 warning generated.
vim +/if +702 drivers/net/can/sja1000/peak_pci.c
38034518c086fc Wolfgang Grandegger 2011-09-12 550
1dd06ae8db716e Greg Kroah-Hartman 2012-12-06 551 static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
38034518c086fc Wolfgang Grandegger 2011-09-12 552 {
38034518c086fc Wolfgang Grandegger 2011-09-12 553 struct sja1000_priv *priv;
38034518c086fc Wolfgang Grandegger 2011-09-12 554 struct peak_pci_chan *chan;
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 555 struct net_device *dev, *prev_dev;
38034518c086fc Wolfgang Grandegger 2011-09-12 556 void __iomem *cfg_base, *reg_base;
38034518c086fc Wolfgang Grandegger 2011-09-12 557 u16 sub_sys_id, icr;
38034518c086fc Wolfgang Grandegger 2011-09-12 558 int i, err, channels;
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 559 char fw_str[14] = "";
38034518c086fc Wolfgang Grandegger 2011-09-12 560
38034518c086fc Wolfgang Grandegger 2011-09-12 561 err = pci_enable_device(pdev);
38034518c086fc Wolfgang Grandegger 2011-09-12 562 if (err)
38034518c086fc Wolfgang Grandegger 2011-09-12 563 return err;
38034518c086fc Wolfgang Grandegger 2011-09-12 564
38034518c086fc Wolfgang Grandegger 2011-09-12 565 err = pci_request_regions(pdev, DRV_NAME);
38034518c086fc Wolfgang Grandegger 2011-09-12 566 if (err)
38034518c086fc Wolfgang Grandegger 2011-09-12 567 goto failure_disable_pci;
38034518c086fc Wolfgang Grandegger 2011-09-12 568
38034518c086fc Wolfgang Grandegger 2011-09-12 569 err = pci_read_config_word(pdev, 0x2e, &sub_sys_id);
38034518c086fc Wolfgang Grandegger 2011-09-12 570 if (err)
38034518c086fc Wolfgang Grandegger 2011-09-12 571 goto failure_release_regions;
38034518c086fc Wolfgang Grandegger 2011-09-12 572
38034518c086fc Wolfgang Grandegger 2011-09-12 573 dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n",
38034518c086fc Wolfgang Grandegger 2011-09-12 574 pdev->vendor, pdev->device, sub_sys_id);
38034518c086fc Wolfgang Grandegger 2011-09-12 575
38034518c086fc Wolfgang Grandegger 2011-09-12 576 err = pci_write_config_word(pdev, 0x44, 0);
38034518c086fc Wolfgang Grandegger 2011-09-12 577 if (err)
38034518c086fc Wolfgang Grandegger 2011-09-12 578 goto failure_release_regions;
38034518c086fc Wolfgang Grandegger 2011-09-12 579
38034518c086fc Wolfgang Grandegger 2011-09-12 580 if (sub_sys_id >= 12)
38034518c086fc Wolfgang Grandegger 2011-09-12 581 channels = 4;
38034518c086fc Wolfgang Grandegger 2011-09-12 582 else if (sub_sys_id >= 10)
38034518c086fc Wolfgang Grandegger 2011-09-12 583 channels = 3;
38034518c086fc Wolfgang Grandegger 2011-09-12 584 else if (sub_sys_id >= 4)
38034518c086fc Wolfgang Grandegger 2011-09-12 585 channels = 2;
38034518c086fc Wolfgang Grandegger 2011-09-12 586 else
38034518c086fc Wolfgang Grandegger 2011-09-12 587 channels = 1;
38034518c086fc Wolfgang Grandegger 2011-09-12 588
38034518c086fc Wolfgang Grandegger 2011-09-12 589 cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE);
38034518c086fc Wolfgang Grandegger 2011-09-12 590 if (!cfg_base) {
38034518c086fc Wolfgang Grandegger 2011-09-12 591 dev_err(&pdev->dev, "failed to map PCI resource #0\n");
4a4bfdcd295728 Peter Senna Tschudin 2012-10-03 592 err = -ENOMEM;
38034518c086fc Wolfgang Grandegger 2011-09-12 593 goto failure_release_regions;
38034518c086fc Wolfgang Grandegger 2011-09-12 594 }
38034518c086fc Wolfgang Grandegger 2011-09-12 595
38034518c086fc Wolfgang Grandegger 2011-09-12 596 reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels);
38034518c086fc Wolfgang Grandegger 2011-09-12 597 if (!reg_base) {
38034518c086fc Wolfgang Grandegger 2011-09-12 598 dev_err(&pdev->dev, "failed to map PCI resource #1\n");
4a4bfdcd295728 Peter Senna Tschudin 2012-10-03 599 err = -ENOMEM;
38034518c086fc Wolfgang Grandegger 2011-09-12 600 goto failure_unmap_cfg_base;
38034518c086fc Wolfgang Grandegger 2011-09-12 601 }
38034518c086fc Wolfgang Grandegger 2011-09-12 602
38034518c086fc Wolfgang Grandegger 2011-09-12 603 /* Set GPIO control register */
38034518c086fc Wolfgang Grandegger 2011-09-12 604 writew(0x0005, cfg_base + PITA_GPIOICR + 2);
38034518c086fc Wolfgang Grandegger 2011-09-12 605 /* Enable all channels of this card */
38034518c086fc Wolfgang Grandegger 2011-09-12 606 writeb(0x00, cfg_base + PITA_GPIOICR);
38034518c086fc Wolfgang Grandegger 2011-09-12 607 /* Toggle reset */
38034518c086fc Wolfgang Grandegger 2011-09-12 608 writeb(0x05, cfg_base + PITA_MISC + 3);
276b7361bb1be3 Jia-Ju Bai 2018-04-11 609 usleep_range(5000, 6000);
38034518c086fc Wolfgang Grandegger 2011-09-12 610 /* Leave parport mux mode */
38034518c086fc Wolfgang Grandegger 2011-09-12 611 writeb(0x04, cfg_base + PITA_MISC + 3);
38034518c086fc Wolfgang Grandegger 2011-09-12 612
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 613 /* FPGA equipped card if not 0 */
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 614 if (readl(cfg_base + PEAK_VER_REG1)) {
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 615 /* FPGA card: display version of the running firmware */
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 616 u32 fw_ver = readl(cfg_base + PEAK_VER_REG2);
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 617
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 618 snprintf(fw_str, sizeof(fw_str), " FW v%u.%u.%u",
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 619 (fw_ver >> 12) & 0xf,
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 620 (fw_ver >> 8) & 0xf,
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 621 (fw_ver >> 4) & 0xf);
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 622 }
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 623
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 624 /* Display commercial name (and, eventually, FW version) of the card */
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 625 dev_info(&pdev->dev, "%ux CAN %s%s\n",
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 626 channels, (const char *)ent->driver_data, fw_str);
805ff68c8e7f4d Stéphane Grosjean 2021-06-07 627
38034518c086fc Wolfgang Grandegger 2011-09-12 628 icr = readw(cfg_base + PITA_ICR + 2);
38034518c086fc Wolfgang Grandegger 2011-09-12 629
38034518c086fc Wolfgang Grandegger 2011-09-12 630 for (i = 0; i < channels; i++) {
38034518c086fc Wolfgang Grandegger 2011-09-12 631 dev = alloc_sja1000dev(sizeof(struct peak_pci_chan));
38034518c086fc Wolfgang Grandegger 2011-09-12 632 if (!dev) {
38034518c086fc Wolfgang Grandegger 2011-09-12 633 err = -ENOMEM;
38034518c086fc Wolfgang Grandegger 2011-09-12 634 goto failure_remove_channels;
38034518c086fc Wolfgang Grandegger 2011-09-12 635 }
38034518c086fc Wolfgang Grandegger 2011-09-12 636
38034518c086fc Wolfgang Grandegger 2011-09-12 637 priv = netdev_priv(dev);
38034518c086fc Wolfgang Grandegger 2011-09-12 638 chan = priv->priv;
38034518c086fc Wolfgang Grandegger 2011-09-12 639
38034518c086fc Wolfgang Grandegger 2011-09-12 640 chan->cfg_base = cfg_base;
38034518c086fc Wolfgang Grandegger 2011-09-12 641 priv->reg_base = reg_base + i * PEAK_PCI_CHAN_SIZE;
38034518c086fc Wolfgang Grandegger 2011-09-12 642
38034518c086fc Wolfgang Grandegger 2011-09-12 643 priv->read_reg = peak_pci_read_reg;
38034518c086fc Wolfgang Grandegger 2011-09-12 644 priv->write_reg = peak_pci_write_reg;
38034518c086fc Wolfgang Grandegger 2011-09-12 645 priv->post_irq = peak_pci_post_irq;
38034518c086fc Wolfgang Grandegger 2011-09-12 646
38034518c086fc Wolfgang Grandegger 2011-09-12 647 priv->can.clock.freq = PEAK_PCI_CAN_CLOCK;
38034518c086fc Wolfgang Grandegger 2011-09-12 648 priv->ocr = PEAK_PCI_OCR;
38034518c086fc Wolfgang Grandegger 2011-09-12 649 priv->cdr = PEAK_PCI_CDR;
38034518c086fc Wolfgang Grandegger 2011-09-12 650 /* Neither a slave nor a single device distributes the clock */
38034518c086fc Wolfgang Grandegger 2011-09-12 651 if (channels == 1 || i > 0)
38034518c086fc Wolfgang Grandegger 2011-09-12 652 priv->cdr |= CDR_CLK_OFF;
38034518c086fc Wolfgang Grandegger 2011-09-12 653
38034518c086fc Wolfgang Grandegger 2011-09-12 654 /* Setup interrupt handling */
38034518c086fc Wolfgang Grandegger 2011-09-12 655 priv->irq_flags = IRQF_SHARED;
38034518c086fc Wolfgang Grandegger 2011-09-12 656 dev->irq = pdev->irq;
38034518c086fc Wolfgang Grandegger 2011-09-12 657
38034518c086fc Wolfgang Grandegger 2011-09-12 658 chan->icr_mask = peak_pci_icr_masks[i];
38034518c086fc Wolfgang Grandegger 2011-09-12 659 icr |= chan->icr_mask;
38034518c086fc Wolfgang Grandegger 2011-09-12 660
38034518c086fc Wolfgang Grandegger 2011-09-12 661 SET_NETDEV_DEV(dev, &pdev->dev);
3e66d0138c05d9 Christopher R. Baker 2014-03-08 662 dev->dev_id = i;
38034518c086fc Wolfgang Grandegger 2011-09-12 663
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 664 /* Create chain of SJA1000 devices */
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 665 chan->prev_dev = pci_get_drvdata(pdev);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 666 pci_set_drvdata(pdev, dev);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 667
9b69aff9fd1a66 Marc Kleine-Budde 2021-06-11 668 /* PCAN-ExpressCard needs some additional i2c init.
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 669 * This must be done *before* register_sja1000dev() but
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 670 * *after* devices linkage
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 671 */
4be0015c955a9a Oliver Hartkopp 2014-09-16 672 if (pdev->device == PEAK_PCIEC_DEVICE_ID ||
4be0015c955a9a Oliver Hartkopp 2014-09-16 673 pdev->device == PEAK_PCIEC34_DEVICE_ID) {
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 674 err = peak_pciec_probe(pdev, dev);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 675 if (err) {
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 676 dev_err(&pdev->dev,
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 677 "failed to probe device (err %d)\n",
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 678 err);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 679 goto failure_free_dev;
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 680 }
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 681 }
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 682
38034518c086fc Wolfgang Grandegger 2011-09-12 683 err = register_sja1000dev(dev);
38034518c086fc Wolfgang Grandegger 2011-09-12 684 if (err) {
38034518c086fc Wolfgang Grandegger 2011-09-12 685 dev_err(&pdev->dev, "failed to register device\n");
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 686 goto failure_free_dev;
38034518c086fc Wolfgang Grandegger 2011-09-12 687 }
38034518c086fc Wolfgang Grandegger 2011-09-12 688
38034518c086fc Wolfgang Grandegger 2011-09-12 689 dev_info(&pdev->dev,
38034518c086fc Wolfgang Grandegger 2011-09-12 690 "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
38034518c086fc Wolfgang Grandegger 2011-09-12 691 dev->name, priv->reg_base, chan->cfg_base, dev->irq);
38034518c086fc Wolfgang Grandegger 2011-09-12 692 }
38034518c086fc Wolfgang Grandegger 2011-09-12 693
38034518c086fc Wolfgang Grandegger 2011-09-12 694 /* Enable interrupts */
38034518c086fc Wolfgang Grandegger 2011-09-12 695 writew(icr, cfg_base + PITA_ICR + 2);
38034518c086fc Wolfgang Grandegger 2011-09-12 696
38034518c086fc Wolfgang Grandegger 2011-09-12 697 return 0;
38034518c086fc Wolfgang Grandegger 2011-09-12 698
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 699 failure_free_dev:
d0c5c584fb3542 Guangshuo Li 2026-09-16 700 if (!chan->prev_dev && chan->pciec_card)
d0c5c584fb3542 Guangshuo Li 2026-09-16 701 peak_pciec_remove(chan->pciec_card);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 @702 pci_set_drvdata(pdev, chan->prev_dev);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 703 free_sja1000dev(dev);
e6d9c80b7ca150 Stéphane Grosjean 2012-03-02 704
38034518c086fc Wolfgang Grandegger 2011-09-12 705 failure_remove_channels:
38034518c086fc Wolfgang Grandegger 2011-09-12 706 /* Disable interrupts */
38034518c086fc Wolfgang Grandegger 2011-09-12 707 writew(0x0, cfg_base + PITA_ICR + 2);
38034518c086fc Wolfgang Grandegger 2011-09-12 708
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 709 for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
38034518c086fc Wolfgang Grandegger 2011-09-12 710 priv = netdev_priv(dev);
38034518c086fc Wolfgang Grandegger 2011-09-12 711 chan = priv->priv;
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 712 prev_dev = chan->prev_dev;
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 713
d0c5c584fb3542 Guangshuo Li 2026-09-16 714 /* do that only for first channel */
d0c5c584fb3542 Guangshuo Li 2026-09-16 715 if (!prev_dev && chan->pciec_card)
d0c5c584fb3542 Guangshuo Li 2026-09-16 716 peak_pciec_remove(chan->pciec_card);
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 717 unregister_sja1000dev(dev);
0b5a958cf4df3a Stéphane Grosjean 2014-05-20 718 free_sja1000dev(dev);
38034518c086fc Wolfgang Grandegger 2011-09-12 719 }
38034518c086fc Wolfgang Grandegger 2011-09-12 720
38034518c086fc Wolfgang Grandegger 2011-09-12 721 pci_iounmap(pdev, reg_base);
38034518c086fc Wolfgang Grandegger 2011-09-12 722
38034518c086fc Wolfgang Grandegger 2011-09-12 723 failure_unmap_cfg_base:
38034518c086fc Wolfgang Grandegger 2011-09-12 724 pci_iounmap(pdev, cfg_base);
38034518c086fc Wolfgang Grandegger 2011-09-12 725
38034518c086fc Wolfgang Grandegger 2011-09-12 726 failure_release_regions:
38034518c086fc Wolfgang Grandegger 2011-09-12 727 pci_release_regions(pdev);
38034518c086fc Wolfgang Grandegger 2011-09-12 728
38034518c086fc Wolfgang Grandegger 2011-09-12 729 failure_disable_pci:
38034518c086fc Wolfgang Grandegger 2011-09-12 730 pci_disable_device(pdev);
38034518c086fc Wolfgang Grandegger 2011-09-12 731
5c2cb02edf79ad Stéphane Grosjean 2017-11-23 732 /* pci_xxx_config_word() return positive PCIBIOS_xxx error codes while
5c2cb02edf79ad Stéphane Grosjean 2017-11-23 733 * the probe() function must return a negative errno in case of failure
9b69aff9fd1a66 Marc Kleine-Budde 2021-06-11 734 * (err is unchanged if negative)
9b69aff9fd1a66 Marc Kleine-Budde 2021-06-11 735 */
5c2cb02edf79ad Stéphane Grosjean 2017-11-23 736 return pcibios_err_to_errno(err);
38034518c086fc Wolfgang Grandegger 2011-09-12 737 }
38034518c086fc Wolfgang Grandegger 2011-09-12 738
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-16 19:08 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-15 17:31 [PATCH] can: peak_pci: fix PCIeC cleanup on probe failure Guangshuo Li
2026-09-16 17:30 ` kernel test robot
2026-09-16 19:07 ` kernel test robot
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®